Typescript联合类型引发错误

时间:2020-02-04 08:54:56

标签: typescript typescript-typings

我定义的对象:

export const exceptionMsg: ErrorMessages = {
    badRequest: 'bla bla bla',
    user: {
       notFound: 'The user bla bla bla',
    },
};

我为它定义的接口 ErrorMessages

interface ErrorMessages {
    [x: string]: string | { [x: string]: string };
}

基本上,我对象的属性可以是字符串,也可以是值也是字符串的对象。这就是我要定义的。但是,在另一个文件中使用此对象时,会引发此错误:

类型'string |中不存在属性'notFound' {[x:string]:字符串; }'。 属性'notFound'在类型'string'上不存在。

我使用它的代码就是这样:

throw new BadRequestException(exceptionMsg.pipeline.notFound);

我对Typescript还是比较陌生,但是在阅读了文档之后,我似乎找不到我所缺少的东西。

1 个答案:

答案 0 :(得分:1)

问题在于,当您将exceptionMsg声明为ErrorMessages时,来自初始化程序的任何信息(例如属性userbadRequest)都会丢失,只有声明的类型{{ 1}}是关于ErrorMessages的。

因此,当您访问exceptionMsg时,基于exceptionMsg.user中的签名的ts仅知道ErrorMessages的类型为exceptionMsg.user。当您具有联合类型的属性时,由于该属性可以是这些类型中的任何一个,因此仅访问两种类型共有的属性是安全的,因此当您再次进行向下钻取时,会像string | { [x: string]: string }一样收到错误消息没有索引签名或string属性。

您可以使用类型保护来缩小类型:

notFound

Playground Link

您可能真正想要的是从常量类型中删除if (typeof exceptionMsg.user !== "string") { exceptionMsg.user.notFound } ,然后进行推断。如果要限制常量以扩展ErrorMessages,可以使用通用函数:

ErrorMessages

Playground Link