我有以下几点:
type gio = {
metadata: any;
}
let a:gio | string;
问题:键入 a.metadata
会产生错误 Property 'metadata' does not exist on type 'string | gio'.
答案 0 :(得分:3)
试试这个:
type gio = {
metadata: any;
}
let a: gio | string;
if(typeof a !== 'string'){
a.metadata
}
答案 1 :(得分:1)
|
将获取包含在这两种类型中的所有属性 - 因此它的类型将是 gio
和 string
之间的公共属性。由于 string
没有 metadata
属性,因此不会包含在最终类型中。你需要的是&
:
type gio = {
metadata: any;
}
let a:gio & string;
这样 gio 和 string 的属性将被组合在一起,您将能够访问 a.matadata
答案 2 :(得分:1)
编辑:snaksa's answer 使用 intersection types 会起作用,但区别在于 let a: gio & string
意味着任何值 a
设置为必须是有效的 gio
还有一个有效的字符串,这意味着它必须具有元数据字段以及字符串的所有成员(length、indexOf()、trim()等) .
这类似于写 interface MyNewType implements gio, string
TypeScript 只允许你使用联合做一些事情,如果联合的每个成员都有效。
例如,如果 gio
被定义为:
type gio = {
metadata: any;
length: number;
}
您可以访问 a.length
,因为 gio
和 string
都有一个长度字段。
另一方面,您不能访问 a.metadata
,因为 a
可能是 string
,也不能访问 a.indexOf()
,因为它可能是 gio
解决办法是用代码缩小联合...
例如,TypeScript 知道只有一个字符串值才会有一个 typeof 值“string”:
所以,as Dor ben Itzhak answered:
if(typeof a !== 'string') {
// a is not a string, therefore it is gio
a.metadata
} else {
// a is a string
a.indexOf("foo")
}
或者如果你想告诉 ts“相信我,这是一个 gio”,你可以使用 type assertion:
(a as gio).metadata
为了记录,There's a whole section in the docs for more complicated narrowing