I've got a function that takes in a key, an object, and returns the value of that key in said object. In the event of a string union, I'd like the object to contain all the members of that union as keys.
The function currently looks like this:
const getValue = <T extends string>(key: T) => <O extends { [key in T]: unknown }>(obj: O): O[T] => {
return obj[key];
};
When given a string union of defined keys, this function works as expected:
const key = "A" as "A" | "B" | "C";
// Correctly typed as number | boolean
const value = getValue(key)({
A: 2,
B: 1,
C: true
});
However, I'd like this function to also gracefully handle string
, in which case should add undefined
as a possible return type, i.e.
// Value should be number | boolean | undefined, but is unknown
const otherValue = getValue(key as string)({
A: 2,
B: 1,
C: true
});
I've tried looking into various solutions including infer
usage, but haven't managed to find a solution so far. Is what I'm looking for possible in TypeScript?
Thanks for your time in helping out!
For your convenience, here's a TypeScript Playground link with the above code.
CodePudding user response:
We only need to change the return type to cover a specific case when T
is a broad string
type:
string extends T ? O[keyof O] | undefined : O[T]
If it is string
, then we get all the values of O
and add undefined
.
Looks good!