Home > Mobile >  Correct return type for a property of an object
Correct return type for a property of an object

Time:05-05

Given the following example code:

interface Foo {
    name: string;
    age: number;
}

const foo: Foo = { name: 'lorem', age: 123 };

const useObject = <T>(obj: T) => {
    const getValue = (key: keyof T): [RETURN HERE] => {
        return obj[key];
    }
    return { getValue };
}

const { getValue } = useObject<Foo>(foo);
getValue('name');

What would I need to replace [RETURN HERE] with to give an accurate return type? For example, the type of getValue('name') would be string and the type of getValue('age') would be number.

CodePudding user response:

Use a generic to "store" what key is, then use it in the return type:

const getValue = <K extends keyof T>(key: K): T[K] => {
    return obj[key];
};

And as @AluanHaddad points out, for this case you don't actually need the return type to be explicitly annotated:

// automatically inferred to return T[K]
const getValue = <K extends keyof T>(key: K) => {

Playground

CodePudding user response:

It will not be enough to just paste the return type, because keyof T is not strict enough to infer the type of value based on the key.

interface Foo {
    name: string;
    age: number;
}

const foo: Foo = { name: 'lorem', age: 123 };

const useObject = <T,>(obj: T) => {
    const getValue = <K extends keyof T>(key: K): T[K] => {
        return obj[key];
    }
    return { getValue };
}

const { getValue } = useObject<Foo>(foo);
getValue('name');

CodePudding user response:

You can introduce a generic type K for the function getValue which only allows keys of T to be passed to the function. Afterwards return the type T[K].

const useObject = <T,>(obj: T) => {
    const getValue = <K extends keyof T>(key: K): T[K] => {
        return obj[key];
    }
    return { getValue };
}
  • Related