I want the following example to produce a type error:
interface Person {
age: number;
name: string;
birthday: Date;
}
interface Grid<T> {
columns: {
field: keyof T;
formatter: (value: T[keyof T]) => string;
}[];
}
function draw<T>(grid: Grid<T>) {}
draw<Person>({
columns: [
{
field: "age",
formatter: (value: number) => "",
},
{
field: "name",
formatter: (value: number) => "", // <-- this parameter should be a `string`! However, TS allows this because `T[keyof T]` matches.
},
],
});
To what should I change the type signature for the formatter function so that its parameter matches the type of the field?
Mapped types will do:
interface Person {
age: number;
name: string;
birthday: Date;
}
// here using mapped types
type Grid<T, Out> =
{
columns: {
[K in keyof T]:
{
field: K,
formatter: (value: T[K]) => Out
}
}[keyof T][]
}
// pay attention that it has second argument which mean the output of the formatting
function draw<T>(grid: Grid<T, string>) {}
draw<Person>({
columns: [
{
field: "age",
formatter: value => "" // value inferred as number
},
{
field: "name",
formatter: (value: number) => "", // error as expected
},
],
});
Some explanation of:
type Grid<T, Out> =
{
columns: {
[K in keyof T]:
{
field: K,
formatter: (value: T[K]) => Out
}
}[keyof T][]
}
K in keyof T
[keyof T]
means that we want all values from created object by the mapped type, in result we will get union of all object with field and formatter props
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.