-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Type guard for undefined not working for intersection type #28079
Comments
You may want to send your 👍 to #202. |
I think another way to interpret the behaviour, according to this comment, is that the an enum type is the union type of its members. As the enum is empty its type is the empty union, which is the same as the I would also add an issue on the TypeScript book because this method of writing nominal types seems flawed. |
Can be made to work by switching the enum to a string enum to get the nominality: enum UuidUniverse { UuidType = '' } // <-- Now a string enum
type Uuid = UuidUniverse.UuidType & string
type DataWithUuid = {
id?: Uuid
}
function doSomethingWithUuid(id: Uuid) {
// ...
}
function handleUuid(data: DataWithUuid) {
if (data.id) { // if condition now working as guard against undefined
doSomethingWithUuid(data.id) // <-- Works
}
} Symbol-driven branding doesn't work (for the same reasons as the int-based enums don't work) as Andy has already pointed out. Literal-driven branding does work too: interface Nominal<T/*: must be an enum or a literal */> {
'nominal structural brand': T
}
enum UuidType {}
type Uuid = string & Nominal<UuidType>;
// ... etc. ... |
enum UuidUniverse { UuidType = '' } // <-- Now a string enum
type Uuid = UuidUniverse.UuidType & string If you hover over it you'll see
|
Thanks @svieira, just came here to post that exact same thing as I figured I'll try it based on andys comment on them being different type. But now reading again what @andy-ms says, it means enum UuidUniverse { UuidType = '' } // <-- Now a string enum
type Uuid = UuidUniverse.UuidType & string is equivalent to just enum Uuid { UuidType = '' } Not sure if there are any downsides to using just that, it seems to work correctly for my use case. Which is that we get data from another server as JSON and deserialize it, we have typings for the data and there are some id's that are UUIDs and then some other IDs that are string but not UUID. And we had few bugs where we passed the wrong type of IDs to functions that expected an UUID (as we previously just had Another solution is to use the original code I posted and just add |
I am using an empty enum as intersection with string to augment a nominal type (according to these instructions https://basarat.gitbooks.io/typescript/docs/tips/nominalTyping.html#using-enums). Otherwise it's working correctly, but I'm getting errors from nullable properties even though there is an if check to make sure it's not undefined or null.
TypeScript Version: 3.2.0-dev.20181023
Search Terms: "intersection nullable guard" "intersection undefined guard" "undefined nominal guard" "guard undefined"
Code
Expected behavior:
no errors
Actual behavior:
Playground Link: (+ select strictNullChecks from options)
Related Issues:
The text was updated successfully, but these errors were encountered: