'Typescript - generic return type based on the type of the property of object union

Suppose we have a following type:

type Config = {
    key: "literal_one",
    value: number,
} | {
    key: "literal_two",
    value: string,
}

export type ConfigKey = Config["key"];
// "literal_one"|"literal_two"

How can we implement the following function?

function getConfig(key: ConfigKey) /* : different return type based on key*/ {
    const conf: Config = this.repository.getById (key);
    return conf.value;
}

When I am assigning an object to a variable with the Config type, Typescript definitely knows that it is impossible to set string value when the key is literal_one. And marks this as an error.

const conf: Config = {
    key: "literal_one",
    value: "not number" // Error: Type 'string' is not assignable to type 'number'
};

So, I assume it should be possible to get the particular value type of the Config object and use it as a return value of the function.

How can we force the getConfig function to have a return type based on the given ConfigKey? Maybe using some kind of generics... (I mean not a number|string return type)



Solution 1:[1]

We can use Extract here:

function getConfig<K extends ConfigKey>(key: K): Extract<Config, { key: K }>["value"] {
  // ...
}

We'll extract all members of Config that are assignable to { key: K }, then get the value type of those members.

Playground

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hittingonme