我预期此错误功能会出错(将对象返回数组),但TypeScript不会引发错误:
function foo(bar: boolean, baz: any): string[] {
return bar ? baz : {};
}
这似乎仅在另一个三元分支返回any
[1]时发生。不管any
,TypeScript都不能检测到另一个分支上的错误吗?
[1]我知道不应将baz
键入为any
。本示例来自一个实际项目,该项目并不完全遵循此类最佳实践。另外,编写此代码时unknown
不存在。
答案 0 :(得分:5)
进行类型推断时,TypeScript会选择最佳通用类型(docs)。在您的示例中,编译器必须推断条件表达式的结果类型。¹any
和object
的最佳通用类型是any
。由于any
匹配任何内容,因此没有警告。
如果您改用if
...
function foo(foo: boolean, bar: any): string[] {
if (foo) {
return bar;
} else {
return {};
}
}
...编译器不必推断条件表达式的类型,并在return {}
上报告错误。
¹? :
是条件运算符。它是 a 三元运算符(一个运算符可以接受三个操作数,就像一元运算符可以接受一个操作数,而二进制运算符可以接受两个操作数),目前是JavaScript的(和TypeScript的)仅是三元运算符,但理论上有一天可能会添加另一个三元运算符...
答案 1 :(得分:4)
问题是bar
的类型为any
。三元运算的类型将是两种可能结果类型的并集。在这种情况下,这意味着any | {}
。但是,如何解决联合的规则规定,如果any
是联合的一部分,则整个联合就变成any
(如果是any
(这是任何可能的类型,这是有道理的) )或其他任何内容,因此可以是any
)。
这将是一个错误:
function foo(foo: boolean, bar: string[]): string[] {
return foo ? bar : {}; // Type 'string[] | {}' is not assignable to type 'string[]'
}
注意为避免此类错误,通常应避免使用any
,从3.0开始,您应该选择unknown
,这将是一个错误
function foo(foo: boolean, bar: unknown): string[] {
return foo ? bar : {}; // Type 'unknown' is not assignable to type 'string[]'
}