【发布时间】:2020-03-04 10:00:40
【问题描述】:
我一直在拼命想了解如何使函数类型安全,但一直没能做到。该函数应该接受一个对象并返回一个数字。这是一个非常简单的例子(对于我的实际应用,接口更复杂)。
interface Parent {
id: number;
children: Child[];
}
interface Child {
text: string;
}
const parents: Parent[] = [
{
id: 1,
children: [
{text: 'Child 1a'}, {text: 'Child 1b'},
{text: 'Child 1c'}, {text: 'Child 1d'},
{text: 'Child 1e'}
]
},
{
id: 2,
children: [
{text: 'Child 2a'}, {text: 'Child 2b'}, {text: 'Child 2c'}
]
}
];
function getMaxNumChildren<T>(data: T[], childKey: keyof T) {
return data.reduce((max: number, parent: T) => {
return max > parent[childKey].length ? max : parent[childKey].length;
}, 0);
}
console.log(getMaxNumChildren<Parent>(parents, 'children')); // 5
因此,您可以想象,parent[childKey].length 会引发错误,因为 typescript 实际上并不知道 T[keyof T] 是一个数组。
我尝试过强制转换为any[] 以及其他一些随机的东西,但我似乎无法做到这一点并保持函数纯粹是通用的。有什么想法吗?
【问题讨论】:
-
只要您确定
childKey将始终指向一个数组,您就可以将parent转换为一个数组:(parent[childKey] as Array<any>).length。或者您可以在运行 reduce 之前进行类型检查以确保length存在。或者也许定义一个父类型T扩展它有一个用字符串索引的数组?
标签: typescript