Wrongly passed code using generics and string literal types · Issue #7472 · microsoft/TypeScript (original) (raw)
TypeScript Version:
1.8.7
compiled: tsc --noImplicitAny error.ts
(the behavior is exactly the same with or without --noImplictAny
)
Code
// A self-contained demonstration of the problem follows... type Greeting = "hello" | "goodbye"
const apply = <T extends string,R>(t: T, f: (t:T) => R): R => f(t) const f1 = (a: Greeting) => console.log('greetings') const f2 = (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