2

Is it possible to be explicit on the first generic, but implicit (infer) the 2nd one?

for example a pick function:

function pick<T extends { [K: string]: any }, U extends keyof T>(obj: T, key: U): T[U] {
    return obj[key];
}

interface Obj {
    foo: string;
    bar: string;
}

const obj = {
    foo: 'foo',
    bar: 'bar',
};

// works, available keys are inferred
pick(obj, 'bar');

// error: Expected 2 type arguments, but got 1.
// Is there a way I can tell to TS to infer the 2nd generic instead of expecting it explicitly?
pick<Obj>(obj, '');
Istvan Orban
  • 1,607
  • 3
  • 18
  • 34

1 Answers1

2
const pick = <T extends { [K: string]: any }>(obj: T) => <U extends keyof T>(key: U): T[U] => {
    return obj[key];
}

interface Obj {
    foo: string;
    bar: string;
}

const obj = {
    foo: 'foo',
    bar: 'bar',
};

// works, available keys are inferred
pick(obj)(bar)

// error: Expected 2 type arguments, but got 1.
// Is there a way I can tell to TS to infer the 2nd generic instead of expecting it explicitly?
pick<Obj>(obj)('foo');

You can by currying the function; Let me know if this helps

Shanon Jackson
  • 5,873
  • 1
  • 19
  • 39
  • Yeah, that the one I went with. Unfortunately as I read there isn't a proper solution for partial inference so far :/. Thanks for your answer! – Istvan Orban Aug 11 '19 at 20:57