如何在接口中 link keyof 类型
How to link keyof types within an interface
不确定这是否可行,但它与 keyof
有关,我很难理解...
我目前有这个界面:
interface Column<T> {
header: string;
field: keyof T;
format?: (value: any) => string;
}
它的第一个用途是创建呈现 table 的东西,给定一个对象和列的列表。
const rows = [{name: 'Alice', age: 18}, {name: 'Bob', age: 12}];
type Row = typeof rows[0];
const columns: Column<Row>[] = [
{
header: 'Name',
field: 'name',
format: value => value.toUpperCase(),
},
{
header: 'Age',
field: 'age',
format: value => value.toLocaleString(),
},
];
const renderTable = <T>(rows: T[], columns: Columns<T>[]) { ... }
renderTable(rows, columns);
有没有办法去掉 format
函数中的 any
类型?以某种方式 "link" field
的 keyof T
和 format
的 value
? IE。第一列 value
应该是 string
,第二列应该是 number
?
(我知道手动打印这些会很容易,但是也会向这个 table 添加一些自动魔法的东西,这将利用 field
和format
)
一种方法是依赖 TypeScript 的 mapped types.
这将 "map" 通过泛型传递 (Row
) 中的每个键 (Key in keyof
)。
然后对于每个 Row
键(例如:name
、age
、admin
),我们将为其分配一个您使用属性勾勒出的形状的对象header
、field
和 format
。
但是,由于我们现在知道我们正在使用特定的键(例如:age
),我们可以使用 Key
来引用此映射类型中的 age
和 Row[Key]
引用 age
的类型 (number
).
最后,您不需要带有嵌套对象的键,您只需要对象,这样我们就可以有效地 "pluck" 使用 [keyof Row]
的那些值,查找 [=27= 的所有值] 剩下的是所有可能的列的联合类型,正确键入 field
和 format
。
type Columns<Row> = {
[Key in keyof Row]: {
header: string;
field: Key,
format?: (value: Row[Key]) => string;
}
}[keyof Row]
const rows = [{name: 'Alice', age: 18, admin: true }, {name: 'Bob', age: 12, admin: false}];
type Row = typeof rows[0];
const columns: Columns<Row>[] = [
{
header: 'Name',
field: 'name',
format: value => value.toUpperCase(), // value: string
},
{
header: 'Age',
field: 'age',
format: value => value.toLocaleString(), // value: number
},
{
header: 'Admin',
field: 'admin',
format: value => value.toString(), // value: boolean
},
];
不确定这是否可行,但它与 keyof
有关,我很难理解...
我目前有这个界面:
interface Column<T> {
header: string;
field: keyof T;
format?: (value: any) => string;
}
它的第一个用途是创建呈现 table 的东西,给定一个对象和列的列表。
const rows = [{name: 'Alice', age: 18}, {name: 'Bob', age: 12}];
type Row = typeof rows[0];
const columns: Column<Row>[] = [
{
header: 'Name',
field: 'name',
format: value => value.toUpperCase(),
},
{
header: 'Age',
field: 'age',
format: value => value.toLocaleString(),
},
];
const renderTable = <T>(rows: T[], columns: Columns<T>[]) { ... }
renderTable(rows, columns);
有没有办法去掉 format
函数中的 any
类型?以某种方式 "link" field
的 keyof T
和 format
的 value
? IE。第一列 value
应该是 string
,第二列应该是 number
?
(我知道手动打印这些会很容易,但是也会向这个 table 添加一些自动魔法的东西,这将利用 field
和format
)
一种方法是依赖 TypeScript 的 mapped types.
这将 "map" 通过泛型传递 (Row
) 中的每个键 (Key in keyof
)。
然后对于每个 Row
键(例如:name
、age
、admin
),我们将为其分配一个您使用属性勾勒出的形状的对象header
、field
和 format
。
但是,由于我们现在知道我们正在使用特定的键(例如:age
),我们可以使用 Key
来引用此映射类型中的 age
和 Row[Key]
引用 age
的类型 (number
).
最后,您不需要带有嵌套对象的键,您只需要对象,这样我们就可以有效地 "pluck" 使用 [keyof Row]
的那些值,查找 [=27= 的所有值] 剩下的是所有可能的列的联合类型,正确键入 field
和 format
。
type Columns<Row> = {
[Key in keyof Row]: {
header: string;
field: Key,
format?: (value: Row[Key]) => string;
}
}[keyof Row]
const rows = [{name: 'Alice', age: 18, admin: true }, {name: 'Bob', age: 12, admin: false}];
type Row = typeof rows[0];
const columns: Columns<Row>[] = [
{
header: 'Name',
field: 'name',
format: value => value.toUpperCase(), // value: string
},
{
header: 'Age',
field: 'age',
format: value => value.toLocaleString(), // value: number
},
{
header: 'Admin',
field: 'admin',
format: value => value.toString(), // value: boolean
},
];