-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Call class function with generic arguments inside class gives error 2345 #41899
Comments
This is a correct error. Allowing this would produce an unsoundness: type MyType = {
foo:string
}
class MyClass<T extends MyType = MyType> {
callMe = (arg1:keyof T, arg12:T[typeof arg1]) => null;
testInsideClass = () => {
this.callMe('foo', 'not-working');
}
}
const classInstance = new MyClass<{foo: "not that"}>();
// Causes value "not-working" to inhabit parameter arg12, which has type "not that" in this instantiation
classInstance.testInsideClass(); |
@RyanCavanaugh Thanks a lot! I didn't realize it was allowed for an extended type to change type of one of one of it's properties? But why is this not working then? Sorry if I miss something obvious. type MyType = {
foo:string
}
type MySecondType = {
foo:number
}
class MyClass<T extends MyType = MyType> {}
const classInstance = new MyClass<MySecondType>(); // <- Compiler error here
// Type 'MySecondType' does not satisfy the constraint 'MyType'.
// Types of property 'foo' are incompatible.
// Type 'number' is not assignable to type 'string'.ts(2344) |
The example I showed was subtyping, which is what |
Yes, my hint was maybe it has to do with another aspect of subtyping - maybe this example is better? type MyType = {
foo:string
}
class MyFirstClass<T extends MyType = MyType> {
func1(arg:keyof T) {}
func2(arg1:keyof T, arg2:T[typeof arg1]) {}
constructor() {
// working
this.func1('foo');
// Compiler error: Argument of type 'string' is not assignable to parameter of type 'T[keyof T]'.ts(2345)
this.func2('foo', 'not-working');
}
}
type MySecondType = MyType & {
bar: string
}
class MySecondClass<T extends MySecondType = MySecondType> extends MyFirstClass<T> {
constructor() {
super();
// working
this.func1('bar');
// Compiler error: Argument of type 'string' is not assignable to parameter of type 'T[keyof T]'.ts(2345)
this.func2('foo', 'not-working');
// Compiler error: Argument of type 'string' is not assignable to parameter of type 'T[keyof T]'.ts(2345)
this.func2('bar', 'not-working');
}
}
const classInstance = new MySecondClass<MySecondType>();
// These are working of course:
classInstance.func2('foo', 'working');
classInstance.func2('bar', 'working'); |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
If anyone get the same problem, it seams like this limitation is by design and suggested work-around-pattern is described in #30480. |
TypeScript Version: 4.1.2
Search Terms:
(arg1:keyof T, arg2:T[typeof arg1])
Code
Expected behavior:
Able to call class function callMe from within the class since T extends MyType
Actual behavior:
Compiler says argument of type 'string' is not assignable to parameter of type 'T[keyof T]'.ts(2345)
Playground Link:
Related Issues:
Maybe #39945 is related
The text was updated successfully, but these errors were encountered: