是否可以在下面的代码中分配适当的类型,以使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 []'。ts(2345)
这个想法是要能够像['label', ['two', 'three']]
这样通过并接收['label1', ['two1', 'three2']]
。
如果我们省略类型,则此代码段将成为正确的JS代码,因此我想知道是否有办法在TS中实现相同的结果。
答案 0 :(得分:1)
您可以使用递归类型,例如示例here。
尝试解决该问题的问题在于,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
});
}