Dynamic Generics in Typescript

Viewed 36

In my DB I have different documents:

interface Dog {
    name: string;
}
interface Cat {
    character: string;
}

interface Person {
    wealth: number;
}

interface Data{
    dog:Dog,
    cat:Cat,
    person:Person,
}

And depend on the document name I want to get the document type:

const getStuffFromDb = (type:string):Data.dog|Data.cat|Data.person{
    return apiCall(type);
}

for (const item of ["dog", "cat", "person"]) {
    getStuffFromDb(item);
}

How knowing the name "dog", "cat" or "person", I can infer the type getStuffFromDb returns? What should I put instead of Data.dog|Data.cat|Data.person or how this should look like in the first place?

Data.dog|Data.cat|Data.person is a pseudocode to represent idea, hope it worked.

1 Answers

The type parameter should be restricted to known keys of Data, then it will be possible to lookup value type of this key:

const getStuffFromDb = <T extends keyof Data>(type: T): Data[T] => {
    return apiCall(type);
}

const foo = getStuffFromDb("cat") // foo is Cat

Playground

Related