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
3.5.1 breaks simple unambiguous type guards? #31853
We get some unexpected regression compiler errors in our code base when upgrading to tsc 3.5.1.
We simplified the code for this bug report.
If this isn't a bug, it would be nice to know why this is now expected behavior, and what would be the recommended workaround?
TypeScript Version: 3.5.1
Search Terms: 3.5, 3.5.1, type guard
Code
enumPrimitiveKind{Float,Integer,}functiontest(kind: PrimitiveKind.Float){console.log("bla");}functionworks(kind: PrimitiveKind){if(kind===PrimitiveKind.Float){test(kind);}}functionkaput1<KextendsPrimitiveKind>(kind: K){if(kind===PrimitiveKind.Float){test(kind);}}functionkaput2<KextendsPrimitiveKind>(kind: K&PrimitiveKind){if(kind===PrimitiveKind.Float){test(kind);}}functionguard(kind: any): kind is PrimitiveKind{// Just for reporting the bugreturntrue;}functionkaput3<KextendsPrimitiveKind>(kind: K&PrimitiveKind){if(guard(kind)&&kind===PrimitiveKind.Float){test(kind);}}
Expected behavior:
The compiles without errors (worked in 3.4.0)
Actual behavior:
Compiler error Type 'PrimitiveKind' is not assignable to type 'PrimitiveKind.Float'. for functions kaput1, kaput2 and kaput3.
(As Siegrift found out below, it seems this behavior started from version 3.4.5)
The sample code above has the same errors in every version of TypeScript going back 2.5, so whatever problem you have updating to 3.5.1, this isn't it.
Anders Hejlsberg (@ahejlsberg)Peter Verswyvelen (@ziriax) Sorry, I am not able to see how it is related. And I am curious about why TS is able to infer the enum type when using switch but not when using if. Can you please explain? :)
Emanuel Tesař (@Siegrift) Your playground example declares K type variables in the two functions and then proceeds to not use them. It makes no sense, but is working as intended. The errors in the original example were due to variables of a generic type not being narrowed--which is expected.
Activity
Siegrift commentedon Jun 11, 2019
I am not sure why this doesn't work (and to my newbie understanding it should)... But I have found these workarounds
playground
Siegrift commentedon Jun 11, 2019
Peter Verswyvelen (@ziriax) Btw. for me it won't compile even with TS version 3.4.5
ziriax commentedon Jun 11, 2019
Emanuel Tesař (@Siegrift)
Indeed, we were still using TS 3.4.0, it fails with 3.4.5, nice catch!
Thanks for the working code, it is amazing that a
switchstatement does work! Semantically this should be the same as anifstatement no?PS: Of course your function
kaput4is not kaput anymore 😉[-]3.5.1 breaks simple unambiguous type guards?[/-][+]3.4.5+ breaks simple unambiguous type guards?[/+][-]3.4.5+ breaks simple unambiguous type guards?[/-][+]3.5.1 breaks simple unambiguous type guards?[/+]ahejlsberg commentedon Jun 11, 2019
The sample code above has the same errors in every version of TypeScript going back 2.5, so whatever problem you have updating to 3.5.1, this isn't it.
ziriax commentedon Jun 11, 2019
Ouch, then we oversimplified the code that broke, mea culpa, I will revise.
ahejlsberg commentedon Jun 11, 2019
The new errors you're seeing are likely related to #30769 and may be intended.
ziriax commentedon Jun 11, 2019
Anders Hejlsberg (@ahejlsberg) You are 100% correct, the full signature of the code that breaks in our code is
function valueAt<K extends PrimitiveKind>(curve: AnyCurve<K>, time: Time): PrimitiveKindToType[K] {...}From issue #30769 I can understand why this breaks now, but it is going to break a lot of our code base ;-)
Siegrift commentedon Jun 11, 2019
Anders Hejlsberg (@ahejlsberg) Peter Verswyvelen (@ziriax) Sorry, I am not able to see how it is related. And I am curious about why TS is able to infer the enum type when using
switchbut not when usingif. Can you please explain? :)ahejlsberg commentedon Jun 11, 2019
The example declares a type parameter but never uses it.
Siegrift commentedon Jun 11, 2019
No, it uses it in the
testfunction (which is ommited from the snippet). Here is a working playgroundahejlsberg commentedon Jun 11, 2019
Emanuel Tesař (@Siegrift) Your playground example declares
Ktype variables in the two functions and then proceeds to not use them. It makes no sense, but is working as intended. The errors in the original example were due to variables of a generic type not being narrowed--which is expected.