Closed
Description
TypeScript Version: 2.9.2
Search Terms: keyof generic interference
In the example below, the calls to getPropertyX(obj, 'first')
should bind the type of K as 'first'
. However, when the definition of K involves Extract
, the inferred binding is 'first' | 'second'
instead (i.e. all possible keys).
Apropos due to the keyof
changes in 2.9.
Code
// Declaration uses keyof -- no problems
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
// Type argument uses bare keyof, function argument uses Extract (doesn't work)
function getProperty2<T, K extends keyof T>(obj: T, key: Extract<K, string>): T[K] {
return obj[key];
}
// Type argument uses Extract (doesn't work)
function getProperty3<T, K extends Extract<keyof T, string>>(obj: T, key: K): T[K] {
return obj[key];
}
interface StrNumPair {
first: string,
second: number,
}
const obj: StrNumPair = {} as any;
let prop: string;
// Works
prop = getProperty(obj, 'first');
// Doesn't work -- string | number is not assignable to string
prop = getProperty2(obj, 'first');
// Doesn't work -- string | number is not assignable to string
prop = getProperty3(obj, 'first');
// Explicit generic binding -- works
prop = getProperty2<StrNumPair, 'first'>(obj, 'first');
prop = getProperty3<StrNumPair, 'first'>(obj, 'first');
Expected behavior: K is bound to just the key passed ('first')
Actual behavior: K is bound to all possible keys ('first' | 'second').
Related Issues: