TypeScript: Property is not assignable to the same property in generic base type
TypeScript Version: 3.3.3333
Search Terms:
Code
interface IFoo<T> {
test<T2, P extends keyof T2>(obj: T2, property: P): void;
}
class Foo<T> implements IFoo<T> {
test<T2, P extends keyof T2>(obj: T2, property: P): void {
}
}
Expected behavior: No error
Actual behavior:
error TS2416: Property 'test' in type 'Foo<T>' is not assignable to the same property in base type 'IFoo<T>'.
Type '<T2, P extends keyof T2>(obj: T2, property: P) => void' is not assignable to type '<T2, P extends keyof T2>(obj: T2, property: P) => void'. Two different types with this name exist, but they are unrelated.
Types of parameters 'property' and 'property' are incompatible.
Type 'P' is not assignable to type 'keyof T2'.
Type 'keyof T2' is not assignable to type 'keyof T2'. Two different types with this name exist, but they are unrelated.
Type 'string | number | symbol' is not assignable to type 'keyof T2'.
Type 'string' is not assignable to type 'keyof T2'.
The following works with no error:
interface IFoo<T> {
test<T2, P extends keyof T2>(obj: T2, property: P): void;
test<T2, P extends keyof T2>(obj: T2, property: P): void;
}
class Foo<T> implements IFoo<T> {
test<T2, P extends keyof T2>(obj: T2, property: P): void {
}
}
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 11
- Comments: 19 (4 by maintainers)
Same issue with simple subclassing:
Playground Link
I found what I think is the same bug, here is my alternative minimized repro: https://www.typescriptlang.org/play/#src=interface I<T> { Foo%3F(t%3A T)%3A void%3B } interface X { Foo<T extends I<object>>(c%3A T | I<T>)%3A c is T%3B } class XX implements X { Foo<T extends I<object>>(c%3A T | I<T>)%3A c is T { return false%3B } }
interface I<T> { Foo?(t: T): void; }
interface X { Foo<T extends I<object>>(c: T | I<T>): c is T; }
class XX implements X { Foo<T extends I<object>>(c: T | I<T>): c is T { return false; } }
Using Tsc Version 3.4.3.
@bendavis78 that isn’t a bug
When you overload a method, the overload needs to be compatible with the signature of that method in the extended class. My example was just shorthand for showing that if you have a
User, it can be passed into any place that expects aTable, including an assignment.The goal of TS is to reduce runtime errors, so it’s correct in flagging a bad overload as a compile-time error. This issue is specifically about TS being overzealous with flagging generic overloads, not overloads in general having the wrong arity.
The bug in the original post seems to be fixed as of v4.3.5 playground
I had the same issue, I had to remove those lines :
in my tsconfig.json file
I see this issue in TS 3.7.4 as well. If I add another signature, i.e. overloading, then TS is happy.