Issue
I have 2 functions with slightly different signatures:
const getValue = <TObj>(obj: TObj, key: keyof TObj) => {
return obj[key];
};
const getValueMultiple = <TObj, TKey extends keyof TObj>(obj: TObj, key: TKey) => {
return obj[key];
};
const result1 = getValue({ a: 1, b: 'some-text', c: true }, 'c');
// result1: string | number | boolean
const result2 = getValueMultiple({ a: 1, b: 'some-text', c: true }, 'c');
//const result2: boolean
I can't understand why in the first case result1 is of type string|number|boolean
( I expected it to be boolean), and why in the second case result2 type is inferred as expected.
I'd appreciate help or reference to the relevant documentation.
Solution
From my understanding, here's how TypeScript sees
const getValue = <TObj>(obj: TObj, key: keyof TObj) => {
return obj[key];
};
// equivalent to
const getValue = <TObj>(obj: TObj, key: keyof TObj): TObj[keyof TObj] => {
return obj[key];
};
const getValueMultiple = <TObj, TKey extends keyof TObj>(obj: TObj, key: TKey) => {
return obj[key];
};
// equivalent to
const getValueMultiple = <TObj, TKey extends keyof TObj>(obj: TObj, key: TKey): TObj[TKey] => {
return obj[key];
};
At first you may think there is no difference but there actually is;
let's take TObj as { a: number, b: string, c: boolean }
TObj[keyof TObj] = TObj["a" | "b" | "c" ] = number | string | boolean
however, concerning TObj[TKey], since TKey is precisely one of "a" | "b" | "c" and TypeScript knows which one it is via the generic param TKey extends keyof TObj
, you get a precise return type.
Answered By - whygee
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.