TypeScript Version: 4.0.2
Search Terms: type narrowing, intersection, property, any, type loss, property widening, generic type narrowing, instanceof, typeof
Code
This shows how ts fails to preserve generic types after narrowing the type with instanceof:
classA<T>{constructor(publicvalue: T){}}constfn=<T>(value: T)=>{if(valueinstanceofA){returnvalue;}returnundefined;};constfn=wrap(newA(42));if(test){typevalueType=typeoftest.value;// any}The inferred result of wrap is T & A<any>. Because of any's (or unknown's) widening nature, there is type information loss (widening to unsafe any on properties).
Expected behavior:
Instead of using & in the inferred result, could we use a conditional type instead? At the moment, I do this by hand:
classA<T>{constructor(publicvalue: T){}}constfn=<T>(value: T)=>{if(valueinstanceofA){returnvalueasanyasExtract<T,A<any>>;}returnundefined;};consttest=fn(newA(42));if(test){typevalueType=typeoftest.value;// number}Actual behavior:
TypeScript creates intersections, causing generic property type loss.
Playground Link:https://www.typescriptlang.org/play?jsx=0&ts=4.0.2#code/N4Ag9GIA4E4PYCMA2BTAtgWAFAhAYyQEMBnYkAQQB4AVAPhGG11zzgDtiAXGAVz07gwAFFB7IAlnhAA3Qkh4oAXCGoBKBgF8mILVm2sOnEAHcYhKCAC8IGrSGz5Slesv1GOZuIBmIe3IUg4oaEbHgocD7k6u7MzDAonDwwbDL+KADc2ri6WSDxickgPGwAJiheQSglmR4aNfrsXCCcKE3WpuZCbCjGFEIALABMqqr1Ht6+LVzRuZwAnlAoqY7UC0vW84sRza2cAHQOCungkCFz2ro5WKAQ0HCk4shLxHDynOLs+kSkFLYMuQYuLx+IIRGIkJJlgplGpNBdsA1DCYzBZrLY-I4YS43LkJhiAkEuCEwtsov8PLF8kkUocliQQGcGWQAKIAD24hH4NAANL8zrRaDVYldKQlqUVSuVKtULmMWI0jFMjO0UV0en0hiM5YEfEIlTMKc01lCUKtFlYjVsfEqDmljrc2Dw0AgUDB4VhdEA
Related Issues:
Related from far #37993
TypeScript Version: 4.0.2
Search Terms: type narrowing, intersection, property, any, type loss, property widening, generic type narrowing, instanceof, typeof
Code
This shows how ts fails to preserve generic types after narrowing the type with
instanceof:The inferred result of
wrapisT & A<any>. Because ofany's (orunknown's) widening nature, there is type information loss (widening to unsafeanyon properties).Expected behavior:
Instead of using
&in the inferred result, could we use a conditional type instead? At the moment, I do this by hand:Actual behavior:
TypeScript creates intersections, causing generic property type loss.
Playground Link:https://www.typescriptlang.org/play?jsx=0&ts=4.0.2#code/N4Ag9GIA4E4PYCMA2BTAtgWAFAhAYyQEMBnYkAQQB4AVAPhGG11zzgDtiAXGAVz07gwAFFB7IAlnhAA3Qkh4oAXCGoBKBgF8mILVm2sOnEAHcYhKCAC8IGrSGz5Slesv1GOZuIBmIe3IUg4oaEbHgocD7k6u7MzDAonDwwbDL+KADc2ri6WSDxickgPGwAJiheQSglmR4aNfrsXCCcKE3WpuZCbCjGFEIALABMqqr1Ht6+LVzRuZwAnlAoqY7UC0vW84sRza2cAHQOCungkCFz2ro5WKAQ0HCk4shLxHDynOLs+kSkFLYMuQYuLx+IIRGIkJJlgplGpNBdsA1DCYzBZrLY-I4YS43LkJhiAkEuCEwtsov8PLF8kkUocliQQGcGWQAKIAD24hH4NAANL8zrRaDVYldKQlqUVSuVKtULmMWI0jFMjO0UV0en0hiM5YEfEIlTMKc01lCUKtFlYjVsfEqDmljrc2Dw0AgUDB4VhdEA
Related Issues:
Related from far #37993