Inferring return type of function based on inferred parameter object value types

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.

>Solution :

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!


Leave a Reply