// 对于 unknown 类型怎么获取其属性值
function getValue(data: unknown) {
// 为什么已经判断 "value" in data,还是会报错
if (typeof data === 'object' && data && 'value' in data) {
return data.value; // error 类型“object”上不存在属性“a”
}
return '';
}
data 类似后端返回的值,这里使用 unknown。上述代码应该怎么改,才能正常获取data属性值,求各位大佬帮忙看看
TypeScript 内置的类型断言有限,但提供了类型断言函数来扩展类型断言。从 Runtime 来看,类型断言函数返回的是一个布尔值,但是从 Compile Time 来看,它可以断言参数是否某一特定类型(声明形式,这个形式表明充值信任 Runtime 的判断结果):
示例:
hasValue(it)
会充分信任 Runtime 对it
的判断,如果返回true
,就认为it
是{ value: unknown }
类型(或其子类型)。所以在getValue()
中,条件表达式为真的情况下,可以识别data
为含有value
属性的类型。注意这里的细节,
value
属性是声明为unknown
类型的。这是基于我们的断言函数里没有去判断value
的类型,只是判断了有没有这个属性。如果期望它是string
类型的,可以修改如下:hasValue()
在没有修改内部逻辑的情况下,声明断言value
是string
类型的。而基于编译器对类型断言的“充分信任”(因为编译器确实对 Runtime 无能为力,只能选择信任声明),getValue()
可以将返回类型修改为string
:条件表达式中,两个分支的类型都是
string
,所以这里不会有问题。但实际上调用的时候,如果给getValue()
一个含有非string
类型value
属性的对象,是可能产生运行时错误的。比如:上面示例,基于类型声明,
s
是string
类型的。但它实际不是string
类型,所以调用substring
会出错。严格一点的
hasStringValue()
应该是这样(hasValue
的逻辑可以合并到hasStringValue
中来减少一个函数):这时候的
s
就会得到""
,也就是表达式的else
分支的值。