javascript - TypeScript:如何确保功能组件的两个道具(数组)具有相同的长度?
问题描述
我正在尝试在反应中制作一个功能组件,它接受两个单独的字符串作为道具。有没有办法使用 TypeScript 确保这两个数组必须具有相同的长度?换句话说,当我们在其他组件中使用这个组件时,除非 props 的长度相同,否则我们会收到错误。
举一个简单的例子,想象一下这样的事情:
export const TableView = ({ s1, s2 }: { s1: string[]; s2: string[] }) => {
return (
<table>
<thead>
<tr>
{s1.map((s, index) => {
return <th>{s1[index]}</th>;
})}
</tr>
</thead>
<tbody>
<tr>
{s2.map((s, index) => {
return <td>{s2[index]}</td>;
})}
</tr>
</tbody>
</table>
);
};
我想确保在将它与不同长度的字符串一起使用时看到错误。
<TableView s1={["1", "2", "3"]} s2={["1", "2", "3", "4"]} />
{/* show an error here */}
解决方案
为了让编译器跟踪输入参数的s1
和s2
元素的长度,你应该在 的类型中进行TableView
泛型s1
,然后用它来检查s2
。因此,调用签名TableView
应该如下所示:
<T extends string[]>({ s1, s2 }: {
s1: [...T];
s2: [...{ [I in keyof T]: string; }];
}) => JSX.Element
这里我们说的T
是一些数组类型的字符串,s1
本质上是 type T
。该语法[...T]
使用可变元组类型语法给编译器一个提示,我们希望它T
作为元组类型而不只是数组类型来解释。元组类型具有已知的顺序和长度,而普通数组类型则没有。你关心长度,所以你想要一个元组类型。
如果我们也可以写[...T]
for那就太好了s2
,但不幸的是,编译器倾向于将 的元素推断T
为字符串文字类型,例如"1"
and"2"
而不是string
. s2
如果是这样,那么这样说[...T]
将限制 的每个元素s2
必须完全等于 的相应元素s1
。我们不想拒绝{s1: ["1", "2"], s2: ["2", "1"]}
,所以我们不能那样做。
因此,我们说这s2
是一个映射元组类型,具有相同数量的元素,s1
但每个值类型都可以是 a string
。
这就是你想要的约束。
让我们测试一下:
<TableView s1={["1", "2", "3"]} s2={["4", "3", "2", "1"]} /> // error!
// --------------------------➨ ~~
// Source has 4 element(s) but target allows only 3.
<TableView s1={["1", "2", "3"]} s2={["4", "3", "2"]} /> // okay
看起来挺好的!
推荐阅读
- azure-devops - 为什么从 GitHub/Kudu 部署后,我的 Azure 函数在函数列表中不可见?
- reactjs - 想知道为什么组件更新时会执行componentWillUnmount
- css - 如何在具有 flex-direction: 'row' 的列上设置不同的高度
- flutter - 使用 Align() Flutter 无法对齐小部件
- python - 为什么在对特定列使用“data.loc”时出现错误?
- javascript - 如何与父母创建 Discord 频道?
- html - Flexbox 不添加顶部填充但添加底部填充
- mongodb - 查询每个文档的数组的不同值
- java - 在使用 SpringFox 的 Swagger Docket 配置中忽略 OAuth2 SecurityReference AuhtorizationScope
- python - 如何修复 - TypeError:无法设置内置/扩展类型“set”的属性