Reputation: 960
I have this code :
declare class Demo<T extends { [key: string]: any }> {
find<K extends keyof T>(key: K): Array<T[K]>;
find(key: string): any
}
const demo1 = new Demo<{ foo: number }>();
const result1 = demo1.find('foo'); // correct (number[])
const result2 = demo1.find('fooo'); // correct (any)
const demo2 = new Demo();
const result3 = demo2.find('test'); // incorrect (any[]), should be any
The comments might speak for themselves, but basically I would like the second overload to be considered for any find
call when no generic was passed to Demo
. Sadly, "test"
satisfies the constraint keyof { [key: string]: any }
, thus the first overload is called. How could I solve this problem ? Thank you.
Upvotes: 2
Views: 56
Reputation: 15136
If it is not a problem to make the class slightly more general, you can constrain T
to object
instead of {[key: string]: any}
to avoid the index-signature issues. An extra & string
in the first find
constraint will prevent it matching non-string keys:
declare class Demo<T extends object> {
find<K extends keyof T & string>(key: K): Array<T[K]>;
find(key: string): any
}
const demo1 = new Demo<{ foo: number }>();
const result1 = demo1.find('foo'); // correct (number[])
const result2 = demo1.find('fooo'); // correct (any)
const demo2 = new Demo();
const result3 = demo2.find('test'); // correct (any)
Upvotes: 2