打字稿字符串或自定义类型

typescript string or custom type

我有以下内容:

type gio = {
    metadata: any;
}


let a:gio | string;

问题:键入 a.metadata 会产生错误 Property 'metadata' does not exist on type 'string | gio'.

试试这个:

type gio = {
    metadata: any;
}


let a: gio | string;

if(typeof a !== 'string'){
    a.metadata
}

| 将采用两种类型中包含的所有属性 - 因此其类型将是 giostring 之间的公共属性。由于 string 没有 metadata 属性 它不会包含在最终类型中。你需要的是 &:

type gio = {
    metadata: any;
}

let a:gio & string;

这样 gio 和 string 的属性将结合在一起,您将能够访问 a.matadata

编辑: using intersection types 会起作用,但不同之处在于 let a: gio & string 意味着任何值 a 都必须是有效的 gio 并且一个有效的字符串,这意味着它必须具有元数据字段以及字符串的所有成员(length,indexOf(),trim (), ETC。)。 它类似于写 interface MyNewType implements gio, string


From the docs:

TypeScript will only allow you to do things with the union if that thing is valid for every member of the union.

例如,如果 gio 定义为:

type gio = {
    metadata: any;
    length: number;
}

您可以访问 a.length,因为 giostring 都有一个长度字段。
另一方面,您无法访问 a.metadata,因为 a 可能是 string,也无法访问 a.indexOf(),因为它可能是 gio

The solution is to narrow the union with code ...
For example, TypeScript knows that only a string value will have a typeof value "string":

所以,:

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