-
-
Notifications
You must be signed in to change notification settings - Fork 354
Support discriminated unions / type narrowing #704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
👀 |
I was looking for a TypeScript narrowing solution for Lua as well. I have to always add ---@return string|number|boolean|nil
local function ExecuteAction()
-- do stuff
end
---@param v any
local function AssertString(v)
assert(type(v) == "string", "Not a string!")
end
local actionName = ExecuteAction()
AssertString(actionName)
---@cast actionName string
local result = actionName .. " executed!" Whereas I would prefer to add some annotation to the I would personally prefer to see annotation that simulates the syntax of TypeScript's narrowing: In TypeScript: function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
// Both calls to 'swim' and 'fly' are now okay.
let pet = getSmallPet();
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
} So, for LuaLS annotation, this could look like: ---@param pet table
---@return pet is Fish
local function IsFish(pet)
return pet.swim ~= nil
end Where returning an For my So maybe that needs to use some sort of ---@asserts value is string
local function AssertString(value)
assert(type(value) == "string", "Not a string!")
end Similar to how TypeScript Assertion Functions work: type Data = { foo: string };
function assertData(d: Data | null): asserts d is Data {
if (d == null)
throw new Error("Invalid data");
}
// Use
declare var bar: Data | null;
bar.foo // error as expected
assertData(bar)
bar.foo // inferred to be Data EDIT: I've created a new follow-up feature request for Assertion Functions that expand on narrowing with type predicates: |
That would be awesome to have this feature, yes! function on_message(self, message_id, message)
if message_id == message_type.ATTACK then
-- autocomplete know the message has `speed` and `health`
print("Speed: " .. message.speed)
print("Health: " .. message.health)
elseif message_id == message_type.JUMP then
-- autocomplete know the message has `height` and `time`
print("Height: " .. message.height)
print("Time: " .. message.time)
end
end |
This is partially implemented in #2864 which supports narrowing for literal fields on classes. |
In TypeScript this is supported by "narrowing"
Consider this example:
For a union type such as 'ActionType' in the example, the only defined properties should be those common to all types. After narrowing (through some sort of type check, in this case a type field) the additional properties in the narrowed subset are also available.
The text was updated successfully, but these errors were encountered: