-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Filter with a type guard fails to narrow when the type guard's predicate is a tuple supertype #59054
Comments
This depends on the filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; With your type predicate you end up with: T // [number | null]
S // [number | string] This |
The second overload here allows the typeguard the work. interface Array<T> {
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
filter<V, S extends V>(predicate: (value: V, index: number, array: T[]) => value is S, thisArg?: any): (T&S)[];
} The problem though is that T and may not be assignable to V, leading to unsafety. V needs a constraint that it is a supertype of T. e.g. type AllowedV<V, T> = T extends V ? V : 'not allowed'
declare global {
interface Array<T> {
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
filter<V, S extends V>(predicate: (value: AllowedV<V, T>, index: number, array: T[]) => value is S, thisArg?: any): (T&S)[];
}
} TS Playground with supertype constraint Seems like we need supertype constraints to make progress on this #14520 |
You would need to write this as declare function Tuple0IsNumberOrString<T>(tuple: [T]): tuple is [T & (number | string)] |
This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π Search Terms
filter type guard failing to narrow tuple supertype
π Version & Regression Information
β― Playground Link
Playground Link
π» Code
More examples on the playground
π Actual behavior
[number | null] & [number | string]
generally gives a result of[number]
, but when a type guard is used with filter (specifically), the result is not the expected type of[number][]
, but rather the input type of[number | null][]
.The problem occurs when the type guard's type assertion is a supertype of the expected item result type
[number]
, but goes away if the type assertion is the same type or a subtype, i.e.[number]
or[5]
. The problem does not occur without the tuple wrapper.π Expected behavior
The filter result should be
[number][]
Additional information about the issue
No response
The text was updated successfully, but these errors were encountered: