对非数组类型使用typeof
类型保护非常简单(来自docs的示例):
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
然而,当涉及到数组类型时,它变得更加复杂。我假设下面的代码可以工作:
function join(array: number[] | string[]): string {
if (typeof array[0] === 'number') {
return foo(array);
} else {
return bar(array)
}
}
function foo(n: number[]): string {
return n.join();
}
function bar(s: string[]): string {
return s.join();
}
对我来说很简单:预期类型是数字数组或字符串数组。
如果数组中第一个元素的类型是number
,那么数组的类型是number[]
。否则,这是一个字符串数组。
不幸的是,TypeScript编译器并不那么聪明,我得到了一个编译错误:
“number[]”类型的参数|“string[]"不能分配给”string[]“类型的参数
我该怎么做?
4条答案
按热度按时间pieyvz9o1#
答案是用户定义的类型保护。
你可以定义一个类型保护,它将决定数组是否是数字数组:
阅读更多关于用户定义的类型保护here。
下面是你的代码的一个工作示例:
TypeScript playground示例。
2uluyalo2#
JeB's answer对我来说是一个很好的开始,但我需要更健壮的东西,因为我必须处理任意输入。我的想法是
velaa5lx3#
下面是一个字符串数组的例子。我想你可以让它通用并测试任何类型:
daupos2t4#
关于类型 predicate 中Typescript的用户定义类型保护的最新文档可以在这里找到。
作为对所选答案的补充,根据typescript文档,您可以在为自定义类型定义typeguards时使用类型Assert: