Imagine having a type defined as:
type Foo = {
foo: number;
bar: string;
baz: boolean;
}
The goal is to create a type Buzz
that can determine the value type for a specific key, such as:
const abc: Buzz<Foo> = {
key: 'foo',
formatter: (detectMe) => {} //The expected result is TS inferring 'number' here
};
When providing the key 'foo', the parameter in formatter should be inferred as number
. Various attempts were made:
interface ColumnDescription<T> {
label: string;
key: keyof T;
formatter?: (datum: T[keyof T]) => void;
}
Unfortunately, this leads to the argument being inferred as number | string | boolean
.
An alternative approach was also tried:
interface ColumnDescription<T, K extends keyof T> {
label: string;
key: K;
formatter?: (datum: T[K]) => void;
}
This solution works but requires specifying the key in the second type argument every time, instead of it happening automatically. For instance:
const abc: Buzz<Foo, 'foo'> = { //I want to avoid specifying the key
key: 'foo',
formatter: (detectMe) => {} //This inference is correct
};