Is there a way to utilize generics to ensure that the type of a value is specific?
// Sample array
const testArr = [
{
id: 3,
name: 'Spaghetto', // Type 'string' here
shouldNotWork: 3.14, // Type 'number' here
},
{
id: 5,
name: 'Bread',
shouldNotWork: 3.14,
},
];
This is my mapping function attempt, but I have to add as V2
to avoid TS complaints :/
type Mapping<T, U> = (val: T, i: number, arr: T[]) => U;
interface Option<T> {
value: T;
label: string; // Required type string
}
const typeToOption = <
T,
K1 extends keyof T,
K2 extends keyof T,
V2 extends T[K2] & string // Union with 'string'
>(
valueK: K1,
labelK: K2,
): Mapping<T, Option<T[K1]>> => (item: T): Option<T[K1]> => ({
value: item[valueK],
label: item[labelK] as V2,
});
I want TS to allow this
const result = testArr.map(typeToOption('id', 'name'));
...but not this
const result = testArr.map(typeToOption('id', 'shouldNotWork'));
How can I make TS complain about the latter scenario?