arrays - 用于反应组件的 Typescript 泛型采用记录数组和键数组
问题描述
我正在尝试创建一个简单的类型化反应组件,用于从对象数组呈现表格。数据输入格式为:
// array of records containing data to render in the table
data = [
{
one: 1,
two: 2,
three: 3,
},
{
one: 11,
two: 22,
three: 33,
}
]
// subset of keys from the data to render in the table
labels = [
'one',
'three',
]
组件如下:
function Table<T extends Record<string, string | number>, K extends Extract<keyof T, string>>({
labels,
data
}: {
labels: K[];
data: T[];
}) {
return (
<table className="table">
{/* ... */}
</table>
);
}
测试它,它似乎只在属性中创建标签时才有效,而不是之前:
// Works
<Table labels={['one']} data={data} />
// Does not work
const labels = ['one']
<Table labels={labels} data={data} />
// Type 'string[]' is not assignable to type '("one" | "two" | "three")'
有谁知道如何修复打字,以便第二种方法有效,而我不必内联创建标签数组?
解决方案
除非必须,否则打字稿不会推断字符串文字类型。如果你写const labels = ['one'];
typescript 会拓宽labels
to的类型string[]
。
您可以通过as const
在 3.4 中使用(尚未发布)来解决此问题,但使用as const
which 将使 ts 推断出一个只读元组labels
const labels = ['one'] as const; // const labels: readonly ["one"]
在 3.4 之前,我们可以使用显式类型:
const labels: ["one"] = ['one'];
或者使用辅助函数提示编译器推断字符串文字和元组:
function stringTuple<T extends string[]>(...a: T){
return a;
}
const labels = stringTuple('one'); // const labels: ["one"]
推荐阅读
- sql - 基于相同的键将多行合并为一行
- java - 在android中查看没有按钮单击的实例
- google-cloud-platform - google cloud firestore datastore模式下实体组对事务的影响
- javascript - html表格水平滚动启用特定列
- c# - .Net Core System.Text.Json 以最小日期时间和 UTC 偏移量失败
- twilio - Twilio 出站 IVR
- sql - 如何根据条件合并两个 SQL Server 表?
- .net - 不可为空的日期时间(不)相等与空编译和运行?
- pdf - 如何自动将特定工作表(即“SheetA”)作为 PDF 导出到 Google Drive?
- r - 为什么 gsub 会自动将 Factor 更改为 Character