-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Allowing type predicate non-assignable to parameter #49779
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
Type guards, and the type system in general, cannot represent a variable changing to a type that is outside the domain of its originating declaration. Changing type predicates won't help the situation; other things would just start breaking instead. |
Going through #17002 and coming up with another one: declare function isArray<T>(arg: T): arg is ToArray<T>;
type ToArray<T> =
0 extends (1 & T) ? any[] :
T extends readonly unknown[] ? T :
T extends Iterable<infer U> | ArrayLike<infer U> ? U[] :
unknown extends T ? unknown[] :
never;
declare const foo: ArrayLike<number> | string[] | number;
if (isArray(foo)) {
// ^?: function isArray<number | ArrayLike<number> | string[]>(arg: number | ArrayLike<number> | string[]): arg is string[] | number[]
foo;
// ^?: string[]
} It fails to resolve to the inferred type predicate result (while Here are my test cases: any -> any[]
unknown -> unknown[]
number -> never
number | number[] -> number[]
number | readonly number[] -> readonly number[]
number | number[] | readonly number[] -> number[]
number | Iterable<number> -> number[]
number | Iterable<number> | number[] -> number[]
number | Iterable<number> | readonly number[] -> number[]
number | ArrayLike<number> -> number[]
number | ArrayLike<number> | number[] -> number[]
number | ArrayLike<number> | readonly number[] -> number[]
number | Iterable<number> | ArrayLike<number> -> number[]
number | Iterable<number> | ArrayLike<number> | number[] -> number[]
number | Iterable<number> | ArrayLike<number> | readonly number[] -> number[]
number | number[] | readonly string[] -> number[] | readonly string[]
number | Iterable<number> | string[] -> number[] | string[]
number | Iterable<number> | readonly string[] -> number[] | readonly string[]
number | ArrayLike<number> | string[] -> number[] | string
number | ArrayLike<number> | readonly string[] -> number[] | readonly string[]
number | Iterable<number> | ArrayLike<string> -> number[] | string[]
number | Iterable<number> | ArrayLike<number> | string[] -> number[] | string[]
number | Iterable<number> | ArrayLike<number> | readonly string[] -> number[] | readonly string[] |
After asking a question in https://stackoverflow.com/questions/72853834, It is found that the above seems to be related to the algorithm described in #47283 (comment). I wonder if #47389 solves this. |
Search Terms: user-defined type guard, assignability
Suggestion: Playground link with relevant code
Expected behavior: No errors, array is inferred as
["foo", "bar"]
Use Cases: uhyo/better-typescript-lib
Discussion: If it needs to be a new syntax, what would be the syntax?
The text was updated successfully, but these errors were encountered: