当我使用其中一个类型为any
的联合类型时,TypeScript编辑器似乎无法正确解析该类型。我有以下人为的例子:
interface ITest {
name: string;
age: number;
}
interface ITest2 {
last: string;
dob: number;
}
function isGood(input: any) : input is ITest{
return 'name' in input && 'age' in input;
}
function doIt(){
var data : ITest2 | ITest = {
last: 'Test', dob: 123
}
var data2 : any | ITest = {
name: 'else', age: 45
}
if(isGood(data)){
alert(`name:${data.name}, age:${data.age}`); // data shows ITest
}
if(isGood(data2)){
alert(`name:${data2.name}, age:${data2.age}`); // data2 shows any
}
}
doIt();
代码正确执行,但设计时间体验并非我所期望的(在VS Code - 1.4.0和TypeScript playground - 1.8中)。
正如预期的那样,以下行根据类型保护推断data
类型为ITest
。
alert(`name:${data.name}, age:${data.age}`); // data shows ITest
但是,第二部分(使用data2
)并未推断出正确的类型,而且总是any
:
alert(`name:${data2.name}, age:${data2.age}`); // data2 shows any
在上面一行中,我希望intellisense知道data2
的类型为ITest
,就像之前为data
一样。
我尝试在联合声明中交换2种类型,但它没有改变结果。
我错过了什么吗?
用例
我面临的真实用例是我收到了一些HTTP调用的响应。在线路上,它必须是any
类型,因为HTTP客户端对我们的数据类型一无所知。
但是,我想写一个用户定义的类型保护,它检查我们想要的json对象的属性,然后只提取我们需要的数据并返回它。
答案 0 :(得分:1)
它扩展了任何类型以包括类型防护。 any
已经超过ITest
,因此它会选择any
。如果您将其更改为更窄的类型,则会正确推断ITest
:
var data2 : {} | ITest = {
name: 'else', age: 45
}
发生这种情况的原因是因为any
是可以想象的最宽的类型,它是同时出现的所有其他类型,所以any | ITest
并不真正有意义,这只是与any
相同。
编辑:我还想指出,只需删除该类型就可以正常工作,即使隐式任何已关闭也是如此。不确定这是否有用。示例:
var data2 = {
name: 'else', age: 45
}
第二次编辑:稍微重写一下答案,以便更清楚,正如评论所示,有一些混乱。