-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Too-permissive assignability with complex discriminated unions #34751
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
Would something like the following work for your use case?
Using this new definition, we get the following (expected) errors when assigning a value to a union of
This solution does have a large difference with the original implementation, in that whether or not a |
@joshuafairchild1 Well not really... The idea is when writing i want a "double discriminate union" - which means that given this: export const h:
| ({ type: '1' } & FilterableTrait<string>)
| ({ type: '2' } & FilterableTrait<number>) = {
type: '2',
isFilterable: true,
filterType: FilterType.Number
}; It should be able to discriminate the |
I think this example gets the essence of the problem without relying on too many other features. Let me know what you think. export const ff:
| { isFilterable: true, filterType: "string" }
| { isFilterable: true, filterType: "number" }
| { isFilterable: false } = {
isFilterable: false,
filterType: "number" // No error? Auto complete doesn't add this as an option but it compiles
}; This seems similar to other union assignability problems we've had. I'll look around for prior art. |
@sandersn Seems like the same problem... One thing to note (maybe not relevant as i dont know how the internal compiler works) is that in my case it uses another generic interface and it seems to mess up the union and intersection relation. Anyway considering what you wrote is the real issue underneath - please make sure generics like in my example will work too. |
First, notice that, without excess property checking, Unfortunately, this doesn't work because both I don't think it's possible to do better without taking exponential time here. A workaround is to add |
I was trying to add type safety to some model i have and it seems to sometimes work in a weird way.
Code
What i did here is created an enum and mapped each entry to a literal type. That way when using the
FilterableTrait
interface it can be eitherFilterable
orNotFilterable
and if filterable theFilterType
is decided based on the given type.Some usages that work
The problem starts when i do this
A few notes here:
Filterable
to befilterType: FilterTypeFromLiteralType<string>
instead offilterType: FilterTypeFromLiteralType<T>
it works... it doesnt work just when i use the generic type.and it will work but my actual use case requires me to use something like
Which means i can't use the above
Expected behavior:
Compilation error
Actual behavior:
Compiles successfully
Playground Link: http://www.typescriptlang.org/play/?ts=3.7-Beta&ssl=31&ssc=3&pln=17&pc=1#
The text was updated successfully, but these errors were encountered: