-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
New "superset" keyword to constrain an union type to be a superset of a sub type. #30099
Comments
Is it the same proposal ? #28586 You can also try this https://github.com/Kotarski/ts-strictargs |
Duplicate of #14520 I think. |
Not sure, even if it looks really similar. My "proposal" is about union where #14520 is more about classes/instances. function foo<T extends ('a' | 'b')>() {} // only 'a', 'b' or ('a' | 'b') allowed as T
function bar<T supersetof ('a' | 'b')>() {} // 'a' not allowed, 'b' not allowed, only ('a' | 'b') or ('a' | 'b' | X) allowed as T |
The examples use interfaces but the proposal is just to add constraints on assigning from, rather than assigning to. This would cover your union case that asserts that the parameter must be assignable from a union type. |
Original is #9252 |
Ye it’s unfortunate that the original uses the terminology upper bounds rather than lower |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
As it may help someone, I found some workaround: interface A<T> {
a: T;
}
interface B<T> extends A<T> {
b: T;
}
interface C<T> {
c: T;
}
type SuperSet<T, U> = {
[key in keyof T]: key extends keyof U
? (U[key] extends T[key] ? T[key] : never)
: T[key]
};
function foo<T extends A<any>>(a: SuperSet<T, A<string>>) {
console.log(a);
}
foo<A<string | number>>((1 as unknown) as A<string | number>); // ok
foo<A<string>>((1 as unknown) as A<string>); // ok
foo<A<number>>((1 as unknown) as A<number>); // invalid
foo<A<number | symbol>>((1 as unknown) as A<number | symbol>); // invalid
foo<B<string | number>>((1 as unknown) as B<string | number>); // ok
foo<B<string>>((1 as unknown) as B<string>); // ok
foo<B<number>>((1 as unknown) as B<number>); // invalid
foo<B<number | symbol>>((1 as unknown) as B<number | symbol>); // invalid
foo<C<string | number>>((1 as unknown) as C<string | number>); // invalid
foo<C<string>>((1 as unknown) as C<string>); // invalid
foo<C<number>>((1 as unknown) as C<number>); // invalid |
Search Terms
extend union type
Suggestion
Currently, there is no way to constrain a type to be a super set of union. For example:
We may imagine a new word:
superset
,supersetof
orsuperset of
to constrain a type to include every sub-types.Use Cases
This would be particularly useful to extends a class with a lot of properties typed with T (attributes or methods) and constrained by a mandatory subset.
Examples
Others
We may imagine some other inferences like:
string
is a superset of an union of strings (ex:string
is a superset of 'a' | 'b')number
is a superset of an union of numbers (ex:number
is a superset of 1 | 2)any
is a superset of an union of anys (ex:any
is a superset of 'a' | 2)number | string
is a superset of 'a' | 2 | 'b'Checklist
My suggestion meets these guidelines:
Related links:
https://stackoverflow.com/questions/45745441/extending-union-type-alias-in-typescript
The text was updated successfully, but these errors were encountered: