typescript - 打字稿多态行为
问题描述
有没有办法在以下代码中分配正确的类型,以便 TS 变得快乐?
function getRowCells<T extends string | string[]>(rowLabels: T[]): T[] {
return [1, 2, 3]
.map((item, i) => {
const labels = rowLabels[i];
if (typeof labels === 'string') {
return labels + item;
}
return getRowCells(labels); // error here, see the description below
});
}
该错误突出显示labels
具有以下错误的标识符:
'T' 类型的参数不能分配给 'string[]' 类型的参数。
键入'字符串 | string[]' 不能分配给类型 'string[]'。
类型 'string' 不可分配给类型 'string[]'.ts(2345)
这个想法是能够通过喜欢['label', ['two', 'three']]
和接收['label1', ['two1', 'three2']]
。
如果我们省略类型,这个片段就会变成正确的 JS 代码,所以我想知道是否有办法在 TS 中实现相同的结果。
解决方案
您可以使用递归类型,例如此处的示例。
您尝试解决问题的问题在于,getRowCells
函数的输出不仅是,string | string[]
而且可能是string | string[] | (string[])[]
,等等......基本上是递归结构。
type ValueOrArray<T> = T | Array<ValueOrArray<T>>;
function getRowCells(rowLabels: ValueOrArray<string>[]): ValueOrArray<string>[] {
return [1, 2, 3]
.map((item, i) => {
const labels = rowLabels[i];
if (typeof labels === 'string') {
return labels + item;
}
return getRowCells(labels); // no error here
});
}
替代方法可能是函数重载,您可以在其中“告诉”打字稿编译器特定的输出作为string[]
输入:
function getRowCells(rowLabels: string[]): string[]
function getRowCells(rowLabels: (string | string[])[]):(string | string[])[] {
return [1, 2, 3]
.map((item, i) => {
const labels = rowLabels[i];
if (typeof labels === 'string') {
return labels + item;
}
return getRowCells(labels); // no error here either
});
}
推荐阅读
- c# - C#:使用 IN 和 OUT 参数执行 Oracle 过程并返回 OUT 参数
- php - Joomla 3.9 - 当我发布了两次由我开发的自定义模块时主页消失了
- c# - 我想通过他们的标签导入我的相关产品
- angular - 如何获取 Angular Material 中下拉列表的相应值?
- facebook-graph-api - 如何使用 Facebook-Api 检查用户是否是 facebook 群组的成员?
- angularjs - 无法设置背景图像属性
- c++ - 无法为 CryptoPP::RSAFunction 链接未定义的 VTT 引用
- html - Flexbox 不尊重 overflow-x: hidden on body (Safari / iOS webkit)
- html - 基础 - 文本在页脚后面继续
- java - 我如何每秒更新电池充电状态