New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Property is not assignable to the same property in generic base type #30071
Comments
I found what I think is the same bug, here is my alternative minimized repro: interface I { interface X { class XX implements X { Using Tsc Version 3.4.3. |
type Key<T extends string | {}> = T extends string ? T : keyof T;
interface Base<T extends string | {}> {
foo(args: Key<T>): void;
}
class WorkingWidget<T extends string | {}> implements Base<T> {
foo(args: Key<T>): void {}
}
class BrokenWidget<T extends string | {}> implements Base<T extends {} ? T : T> {
foo(args: Key<T>): void {}
} Error:
|
This issue still exists on TypeScript 3.7.2: Playground link Compiler Options: {
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": false,
"allowJs": false,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES2017",
"module": "ESNext"
}
} Input: interface Model<S, PK extends keyof S> {
join<S2, PK2 extends keyof S2>(s: S2, pk: PK2): void;
}
class Table<S, PK extends keyof S> implements Model<S, PK> {
public join<S2, PK2 extends keyof S2>(s: S2, pk: PK2): void {
// Dummy implementation
}
} This produces an error claiming that the method is incompatible with the one in the interface even though the signatures are identical:
|
I see this issue in TS 3.7.4 as well. If I add another signature, i.e. overloading, then TS is happy. |
I am using 3.7.5. Having this error.
Got error in child.
|
it does not make sence |
Same issue. how can we address? |
@wannadream That error makes sense to me. Let's say you have: const user: Table = new User(); if you call |
I don't think your example explains the OOP concept. If we overload certain methods, we definitely won't do At least, the TS transpiler should not complain about it as that should be a RUNTIME error in your example. The class itself has nothing wrong, I would say. |
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 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. |
got the same error when using generic abstract class which I really do not understand. The only way to avoid the message is to type the parameter as any in the absctract class which is not efficient. exemple :
class the implements the abstract one
compiler error :
|
Turns out typescript type checks properties different than methods (it impacts variance of generic types differently), and you happen to be able to work around this by changing the member of the interface to a property instead of a method:
|
I had the same issue,
in my tsconfig.json file |
added ts-ignore for microsoft/TypeScript#30071 fixed buffer parsing in json stream parsing fixed webpack on server
Same issue with simple subclassing:
|
@bendavis78 that isn't a bug |
Same issue. // types
interface componentApi {
name: 'vue' | 'react',
entryExt: string
}
interface config {
script: string,
style: string,
componentApi?: componentApi
}
// main
class Config implements config {
public readonly script = 'ts'
public readonly style = 'scss'
//public readonly componentApi = { // not okay
/*
Property 'componentApi' in type 'Config' is not assignable to the same property in base type 'config'.
Type '{ name: string; entryExt: string; }' is not assignable to type 'componentApi'.
Types of property 'name' are incompatible.
Type 'string' is not assignable to type '"vue" | "react"'.
*/
public readonly componentApi: componentApi = { // okay
name: 'react',
entryExt: `${ this.script }x`
}
}
export default new Config() |
@nhhockeyplayer this issue is not a place for freeform complaints; please stay on-topic |
The bug in the original post seems to be fixed as of v4.3.5 playground |
Thanks @webstrand ! |
TypeScript Version: 3.3.3333
Search Terms:
Code
Expected behavior:
No error
Actual behavior:
Playground Link
The following works with no error:
The text was updated successfully, but these errors were encountered: