Runtime Type Checker that reads types in Luau format

I made a type checking library that is able to read type definitions in Luau format, as well as offer common type checking operations. Similar to t (type checker) but it can read Luau type definitions from strings, among other additions like subtype checking and allowing the addition of custom types.

This is an early release and contributions or ideas are welcome.

Organized to be installed with Wally as Type = "meta-maxim/type@^1"

Usage examples:

local Type = require(script.Parent.Type) -- require the library

-- Defines a custom tuple type
local myType = Type("Enum.NormalId, { x: number, y: number }?")

-- Check types
print(myType:Is(Enum.NormalId.Front, nil)) --> true
print(myType:Is(Enum.NormalId.Front, { x = 1 })) --> false

-- Compare types
print(myType == Type("Enum.NormalId", "{ x: number, y: number }?")) --> true

local myItemTemplate = {
  Id = 1;
  RefId = 1;
}

local myItemType = Type [[{
  Id: number;
  RefId: number;
}]]

-- Get type of value
print(Type.of(myItemTemplate) == myItemType) --> true

-- Custom type class construction
print(Type.Union.new(Type.Number, Type.String) == Type("number | string")) --> true

Supporting the latest Roblox data types may require updating dependency lists of names (currently I copy from Roblox API: RobloxDataTypeNames, RobloxClassNames, RobloxInstanceNames

1 Like

Awful way of doing this. Id prefer t instead.

1 Like

I’d agree t has a better approach for this, but that doesn’t mean this library is useless. Someone will find it useful.

1 Like

Curious on what’s awful about the approach?

What part of t’s approach do you think is better? As far as I’m aware this allows constructing types in the exact same way as t, but with additional features. I also personally find the luau-like definitions to be much easier and quicker to write, while also improving readability.

image

This kind of syntax is autocompleted, as opposed to typing the string literal { x: number, y: number }?. It’s also less messy to write t.interface rather than Type [[{ }]]. I guess it’s purely a preference thing, as both accomplish what they’re intended to do, but I’ll be open to using this for a project to see how I like it.

1 Like

the bad usage of strings

1 Like
  1. Depends on what autocomplete you use, I tend to use a newer AI tool that autocompletes the string definitions too.

  2. I also like t.interface in this case but Type.Table(), Type("{}") / Type"{}" might be less messy… I tend to avoid referencing the Type library itself for most of my code, instead I just provide the string definitions as options, and have later systems handle the type creation:

-- A system first registers middleware that calls Type.new() for typechecking if ArgTypes are specified

-- I specify what types to check for when networking: RemoteSignal.new(signalDefinition, signalMetadata)
RemoteSignal.new(..., { ArgTypes = "{}, number" }):Connect(handler)