You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow intersection type guards for multiple parameters #26916
I'd like to write a type guard that takes two parameters and changes the type of both of them.
Use Cases
My specific use case is to try to make the following pattern (somewhat) more type-safe:
classFoo<TFeature,TOther>{// If featureCtor is null, TFeature will never be used.constructor(privatereadonlyfeatureCtor: {new(): TFeature}|null){}isFeature(thing: any): thing is TFeature{return!!this.featureCtor&&thinginstanceofthis.featureCtor;}bar(thing: TFeature|TOther){if(this.isFeature(thing)){// Type guard should prove that this.featureCtor is not nullnewthis.featureCtor();}else{// Type guard should prove thisconstx: TOther=thing;}}}
const isValidPair = (x: null | string, y: null | string): x is string & y is null {
return typeof x === 'string' && y === null;
};
if (isValidPair(var1, var2)) {
// know var1 is string
// know var2 is null
}
Reacted by Guillaume Lecêtre, Klaus Reimer, Jaron Long, Victor Malov, James Newell, Valery, Mokhtar, Safar Ligal, Lucas Menicucci, PavelKoroteev and 70 more
Reacted by Radu, Rafael Tavares, Theodore Gregory, bl-ue, Aleksey Bobyr, Tim Paul, Alexis Rougnant, Sergey Kazantsev, Speros Kokenes, Karina Koola and 3 more
This would be useful for processing overloaded function parameters where it is enough to check one parameter to assume the type of the other parameter:
functionnonsense(a: number,b: number): number;functionnonsense(a: string,b: string): string;functionnonsense(a: number|string,b: number|string): number|string{constisNumbers=(a: number|string,b: number|string): a is number&bisnumber=>typeofa==="number";if(isNumbers(a,b)){returna*10+b*100;}else{returna.length+b.length;}}
Reacted by Alex Barker, Kaat, iBreatheJs, Tim Paul, so/ふかねこ, Jems, Joshua Turner, Jim Higson , Ⓩⓞⓛⓣⓐⓝ Bourne, Huynh Duc Duy and 3 more
Reacted by Kaat, Tim Paul, Joshua Turner, Hugues Le Gendre and matheusrsimon
Reacted by Chris Bellew, Chris, Safar Ligal, Klemen Oslaj, Hugo Drumond, Denis Pshenov, Lev Izraelit, Jacob Nesbitt, Chris Larson, Teodors Zeltins and 30 more
Would be really useful to have this. I wanted something like then when trying to type a deepEqual function:
// Would like assert that BOTH parameters are the intersection of their respective typesexportfunctiondeepEqual<A,B>(a: A,b: B): (aisA&B)&&(bisA&B){...}
if(isArrayOfSets([A,B])){// isArrayOfSets is a type predicate : `array is Set<any>[]` returnisSuperSet([...A],[...B])}
Even though the predicate implicitly guarantees that A and B are both sets, it has lost this knowledge when applied to the arrays constituents. Instead I have to either repeat calls to type predicates for each variable like this:
Another use case for this feature is validating that an object contains a particular key.
Assume I have a Record obj and a string key, where key may be a string literal, a string union type, or a string variable. Today, I'd need two different type guards with the same runtime implementation to validate that obj has an own property of key:
One to narrow key to keyof obj so I can safely write obj[key]
Another to narrow obj to a Record type with a property whose name is type typeof key, so that I can safely pass obj to other functions that require the narrowed type.
Ideally I could have a single type guard function that narrows both obj and key at the same time.
Assume I have a Record obj and a string key, where key may be a string literal, a string union type, or a string variable.
Another to narrow obj to a Record type with a property whose name is type typeof key, so that I can safely pass obj to other functions that require the narrowed type.
If you do this with a union or a wide type like string you'd essentially prove the existence of multiple keys by checking for only one. Isn't that unsafe?
Assume I have a Record obj and a string key, where key may be a string literal, a string union type, or a string variable.
Another to narrow obj to a Record type with a property whose name is type typeof key, so that I can safely pass obj to other functions that require the narrowed type.
If you do this with a union or a wide type like string you'd essentially prove the existence of multiple keys by checking for only one. Isn't that unsafe?
That depends entirely on the runtime implementation. By declaring functions as type guards or assertions, we are already being somewhat less safe by saying "Trust me, Typescript. I know what type this function returns."
Reacted by Bartosz, Justin Grant and Huynh Duc Duy
I don't know if this issue makes the same request, but it would be great if the type guard also cast the others variables with the same generic type
an exemple
const isCat = (pet: Pet): pet is Cat => {
// ...
}
const foo = <T extends Pet>(pet: T, shop: PetShop<T>) => {
if (isCat(pet)) {
// Here "pet" is Cat type, but "shop" is not PetShop<Cat> type
// However, the variables share their T type, so they necessarily have the same
}
}
Valentin Turpault (@polurax) the issue is, just because pet is Cat doesn't mean T is Cat as well. Example where code compiles but T is not Cat even though pet is Cat:
Valentin Turpault (@polurax) the issue is, just because pet is Cat doesn't mean T is Cat as well. Example where code compiles but T is not Cat even though pet is Cat:
foo<Pet>(cat,dogShop)
I understand the problem. But it remains disconcerting.
Thank for the explanation
Bartosz (@burtek)
I know it's not possible because of transpilation in javascript, but having a type guard that works on generic types directly without using a variable would be great.
Activity
jyrodrigues commentedon May 20, 2019
Any news on this?
quisido commentedon Nov 19, 2019
Seconding a need for this:
kayahr commentedon Dec 5, 2019
This would be useful for processing overloaded function parameters where it is enough to check one parameter to assume the type of the other parameter:
Fnxxxxo commentedon Dec 14, 2019
This is also convenient and meaningful for builders.
m5r commentedon Jul 27, 2020
Hi, any updates?
mordv commentedon May 16, 2021
I think it would be useful for otherwise annoying ref.current checking in react
avalanche1 commentedon May 24, 2022
bump!
helmturner commentedon Jul 15, 2022
Would be great for syntax trees, as well.
I actually assumed this was possible, and tried the following syntaxes before finding this issue.
This syntax seems natural:
But it logically follows that a destructuring pattern could be used, as well.
Something like the following:
or:
joyt commentedon Dec 7, 2022
Would be really useful to have this. I wanted something like then when trying to type a
deepEqualfunction:fatso83 commentedon Jan 30, 2023
Currently, the following is not possible:
Even though the predicate implicitly guarantees that A and B are both sets, it has lost this knowledge when applied to the arrays constituents. Instead I have to either repeat calls to type predicates for each variable like this:
Or I need to create throwaway intermediate objects to work around this, bloating the code:
Would be cool to avoid this.
trusktr commentedon Mar 2, 2023
A couple questions for this in the wild:
https://stackoverflow.com/questions/66880821/in-typescript-i-want-to-make-a-type-guard-for-multiple-arguments
https://stackoverflow.com/questions/58636396/type-guard-that-asserts-all-rest-parameters-are-not-undefined
WillsterJohnson commentedon Jun 1, 2023
It's worth noting that without this feature TypeScript is logically inconsistent, see #54479
LiChangyi commentedon Nov 14, 2023
Hi, any updates? I need it.
fatso83 commentedon Nov 14, 2023
If you want it, make it and supply a PR
justingrant commentedon Apr 10, 2024
Another use case for this feature is validating that an object contains a particular key.
Assume I have a Record
objand a stringkey, wherekeymay be a string literal, a string union type, or a string variable. Today, I'd need two different type guards with the same runtime implementation to validate thatobjhas an own property ofkey:keytokeyof objso I can safely writeobj[key]objto a Record type with a property whose name is typetypeof key, so that I can safely passobjto other functions that require the narrowed type.Ideally I could have a single type guard function that narrows both
objandkeyat the same time.bgenia commentedon Apr 10, 2024
If you do this with a union or a wide type like
stringyou'd essentially prove the existence of multiple keys by checking for only one. Isn't that unsafe?helmturner commentedon Apr 10, 2024
That depends entirely on the runtime implementation. By declaring functions as type guards or assertions, we are already being somewhat less safe by saying "Trust me, Typescript. I know what type this function returns."
polurax commentedon May 30, 2024
I don't know if this issue makes the same request, but it would be great if the type guard also cast the others variables with the same generic type
an exemple
burtek commentedon May 30, 2024
Valentin Turpault (@polurax) the issue is, just because
petisCatdoesn't meanTisCatas well. Example where code compiles butTis notCateven thoughpetisCat:polurax commentedon May 30, 2024
I understand the problem. But it remains disconcerting.
Thank for the explanation
polurax commentedon May 30, 2024
Bartosz (@burtek)
I know it's not possible because of transpilation in javascript, but having a type guard that works on generic types directly without using a variable would be great.
Lonli-Lokli commentedon Sep 16, 2024
With a brilliant fix #57465
Is it possible to reconsider if it possible to implement this one too?
sdwvit commentedon Oct 2, 2025
Much needed feature. In the meanwhile I use a workaround: