Asserting an object as a Luau alias

Is it possible to check if a value is of a specific type alias in Luau?

For example:

type foo = { value: string }
local test1 = “Greetings!”
local testIsFoo = --Test for type goes here

I have yet to find an elegant technique to do so. Does anyone know if this is possible?
Thanks.

typeof(Origin) == “CFrame”, as an example, in an if statement ofc

This only works for Roblox-defined types in my experience, not user-defined type aliases.

If you want runtime type checking use t otherwise use Roblox type checking:

--!strict

type foo = { value: string }
local test1 = “Greetings!” :: foo -- errors if type is invalid

This isn’t what I’m looking for - I would like to branch behaviour depending on if a value matches a specific type alias. I would also like to avoid external dependencies.
Thanks for the help anyway.

The only way you can do that is with t.

local isFoo = t.interface(
    value = t.string,
)

local foo = {value = "Hello"}

if isFoo(foo) then print("Valid type") end --prints "Valid type"

To add onto this, if you could provide more context about your use case, I can suggest other alternatives.

I will update the post with the details of the use case after I’ve had my breakfast.

Ok, so what I’m trying to do is implement Rust’s Result<T, E> type in Roblox.

At the moment, that looks a little something like this:

type Ok<T> = { type = "ok", value: T }
type Err<E> = { type = "err", error: E }
type Result<T, E> = Ok<T> | Err<E>

I am able to branch this code using the common type member, but I would much prefer the following:

type Ok<T> = T
type Err<E> = E
type Result<T, E> = Ok<T> | Err<E>

Of course, the issue with this is that you can no longer tell if a result is an Ok<T> or an Err<E>.
Do you have any suggestions?

My current solution involves creating a hidden __index table containing the type within a metatable and then creating a method isOk() and isErr() to make branching easy and maintainable.

However, this increases the complexity of the code significantly and is rather inelegant.
Of course, just comparing the type directly inline is possible, but if I ever need to change the names of the variants, all of that code breaks.