typescript version: 3.9.2
The goal is to define an interface constraint that permits only non-functional member keys on the class
type NonFunctionKeys<T extends {}> = {
[K in keyof T]-?: T[K] extends Function ? never : K
}[keyof T];
class MyClass {
someKey: boolean = true;
set<T extends keyof this>(key:T, value: this[T]) {
}
setValue<T extends NonFunctionKeys<this>>(key:T, value: this[T]) {
}
foo() {
// valid
this.set('someKey', true);
// valid
(this as MyClass).setValue('someKey', true);
// next line will show error
// 2345: Argument of type '"childValue"' is not assignable to parameter of type 'this[keyof this] extends Function ? never : keyof this'.
this.setValue('someKey', true);
}
}
// all good
const c = new MyClass();
c.set('someKey', true)
c.setValue('someKey', true)
Does typescript not acknowledge this
? However, IDE provides correct hints, and type inference is accurate when using attributes
PS: additional note, while the scenario here may seem simple, it actually involves inheritance - the value of the set could be a property of the super class, or in case of inheritance, the subclass might have additional properties, hence why I can't specify MyClass instead of this