Add signatures that enable TypeScript type guards#4
Add signatures that enable TypeScript type guards#4NeilRashbrook wants to merge 2 commits intobenbucksch:masterfrom
Conversation
This enables you to write `.find((e): e is Derived => e instanceof Derived)` and TypeScript will infer the type of the expression to be `Derived` instead of the type of the collection. (Similarly for the other methods.)
|
Why would you not simply declare the collection to be |
|
It contains object of multiple subtypes, but you happen to know that the one you're trying to find has a specific subtype. |
| * order, until it finds one where `filterFunc` returns true. If such an element is found, find | ||
| * immediately returns that element valuehttps://github.com/microsoft/TypeScript/blob/main/src/lib/es2016.array.include.d.tsOtherwise, find returns undefined. | ||
| */ | ||
| find<T extends Item>(filterFunc: (item: Item) => item is T): T; |
There was a problem hiding this comment.
This looks almost the same as the line below. Can we just keep your new one and delete the old one? (Would it break anything?)
There was a problem hiding this comment.
(both comments apply to all changes, not only this one)
There was a problem hiding this comment.
The first line is needed for when the function is being used to find an item of a specific subtype, and the second line is for all other cases.
| * order, until it finds one where `filterFunc` returns true. If such an element is found, find | ||
| * immediately returns that element valuehttps://github.com/microsoft/TypeScript/blob/main/src/lib/es2016.array.include.d.tsOtherwise, find returns undefined. | ||
| */ | ||
| find<T extends Item>(filterFunc: (item: Item) => item is T): T; |
There was a problem hiding this comment.
The filterFunc returns boolean, not an item. It merely says whether the item that was passed into filterFunc is the one that we wanted to find.
There was a problem hiding this comment.
item is T is a special TypeScript subtype of boolean which also asserts that the type of item is T when the value is true.
If you write
for (let value of array) {
if (value instanceof Dervied) {
value.doDerivedSpecificThing();
}
}Typescript recognises the instanceof check as changing the type of value to Derived. You could say that the expression value instanceof Derived has type value is Derived.
However when you're doing something slightly more complicated such as defining the return type of the find function you need to explicitly say that if the match function is of type item is T then the find function will always return an item of type T.
Can you please add this as comment? And please make your additional definition the second line. As-is, the primary definition (which should be first anyways) is losing the JSDoc definition. |
Sorry, but TypeScript requires that the most generic definition be last. |
This enables you to write
.find((e): e is Derived => e instanceof Derived)and TypeScript will infer the type of the expression to beDerivedinstead of the type of the collection. (Similarly for the other methods.)