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
Wrongly passed code using generics and string literal types #7472
compiled: tsc --noImplicitAny error.ts
(the behavior is exactly the same with or without --noImplictAny)
Code
// A self-contained demonstration of the problem follows...typeGreeting="hello"|"goodbye"constapply=<Textendsstring,R>(t: T,f: (t:T)=>R): R=>f(t)constf1=(a: Greeting)=>console.log('greetings')constf2=(a: number)=>console.log(3+a)apply("hello",f1)/* 1. should be good. is good */apply("helo",f1)/* 2a. should be error. is good */apply<Greeting,void>("helo",f1)/* 2b. should be error. is error */apply("hello",f2)/* 3. should be error. is error */apply(3,f1)/* 4. should be error. is error */apply(3,f2)/* 5. should be error. is error */
Expected behavior:
2-5 should have an error:
2 should have an error because "helo" is not a member of "hello"|"goodbye"
3 should have an error because "hello" is not a number
4 should have an error because 3 is not a member of "hello"|"goodbye" and because 3 is not a member of type which extends string
5 should have an error because 3 is not a member of a type which extends string, and because number does not extend string.
Actual behavior:
1, 2b, 3-5 are correct
2a passes typechecking even though it should be equivalent to 2b
Tristan McLeay (@tmcl) explained it to me, the inferred generic parameters for 2a. are <string, void>, because string is the common type between "helo" and Greeting, and (s:Greeting) => void is compatible with (s:string) => void due to function parameter bivariance.
Activity
mhegazy commentedon Mar 11, 2016
Please see https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-function-parameters-bivariant for explanation.
jesseschalken commentedon Mar 11, 2016
Mohamed Hegazy (@mhegazy) Can you explain where function parameter bivariance comes into play here?
jesseschalken commentedon Mar 11, 2016
Tristan McLeay (@tmcl) explained it to me, the inferred generic parameters for 2a. are
<string, void>, becausestringis the common type between"helo"andGreeting, and(s:Greeting) => voidis compatible with(s:string) => voiddue to function parameter bivariance.