gpt4 book ai didi

node.js - 如何正确使用 TypeScript 联合类型?

转载 作者:搜寻专家 更新时间:2023-10-30 21:45:07 27 4
gpt4 key购买 nike

我在使用基本联合类型时遇到问题,感谢您的帮助!构建一个聊天应用程序,其中传入的消息可以具有不同类型的有效负载。所以我创建了一些有效负载类型,例如:

export interface TextPayload {
text: string,
}
export interface ImagePayload {
url: string,
} //etc

使用 |

将它们全部绑定(bind)在一个联合类型中只是为了清楚
export type MessagePayload = TextPayload | ImagePayload | UrlPayload | FilePayload

然后最终消息使用它作为有效负载。

export interface IBotMsg {
payload: MessagePayload // this creates the problem
}

但是在尝试使用时我得到了这个错误

[0]       TS2459: Type 'MessagePayload' has no property 'text' and no string index signature.

此处使用代码。可能是它的解构赋值混淆了类型系统......

  const msg: IBotMsg = req.body.msg
const { payload: { text } } = msg

另一行抛出错误

    let text = msgIn.payload.text

完全错误

[0]
[0] ERROR in ./server/bots/watson/routes/index.ts
[0] [tsl] ERROR in /Users/dc/dev/tix/recobot/stack/backend/server/bots/watson/routes/index.ts(19,22)
[0] TS2459: Type 'MessagePayload' has no property 'text' and no string index signature.
[0]
[0] ERROR in ./server/bots/watson/routes/index.ts
[0] [tsl] ERROR in /Users/dc/dev/tix/recobot/stack/backend/server/bots/watson/routes/index.ts(40,25)
[0] TS2339: Property 'text' does not exist on type 'MessagePayload'.
[0] Property 'text' does not exist on type 'ImagePayload'.
[0]
[0] ERROR in ./server/bots/tix/brain/TixBrain.ts
[0] [tsl] ERROR in /Users/dc/dev/tix/recobot/stack/backend/server/bots/tix/brain/TixBrain.ts(27,30)
[0] TS2339: Property 'text' does not exist on type 'MessagePayload'.
[0] Property 'text' does not exist on type 'ImagePayload'.
[0]
[0] ERROR in /Users/dc/dev/tix/recobot/stack/backend/server/bots/testbot/TestBot.ts
[0] [tsl] ERROR in /Users/dc/dev/tix/recobot/stack/backend/server/bots/testbot/TestBot.ts(12,39)
[0] TS2339: Property 'text' does not exist on type 'MessagePayload'.
[0] Property 'text' does not exist on type 'ImagePayload'.

这几乎就好像编译器只是在 ImagePayload 上中途退出...

联合类型是否意味着属性必须存在于每个 成员上,而不仅仅是一个?子类型必须是接口(interface)的超集?我不太明白这种情况的意义。我也尝试过只使用 TextPayload,例如,不是联合类型,但得到了类似的错误……很困惑。

我对类型和接口(interface)也有点困惑。为什么这不是 UnionInterface

感谢任何提示。

质谱引用 https://www.typescriptlang.org/docs/handbook/advanced-types.html

完整代码

export enum MessageType {
TEXT = 0,
IMAGE = 1,
URL_LINK = 2,
FILE = 3,
}

export interface TextPayload {
text: string,
mention?: string[],
}

export interface ImagePayload {
url: string,
}

export interface UrlPayload {
sourceUrl: string,
title: string,
summary: string,
imageUrl: string,
}

export interface FilePayload {
url: string,
name: string,
}

export type MessagePayload = TextPayload | ImagePayload | UrlPayload | FilePayload

export interface IBotMsg {
chatId?: string,
token?: string,
messageType?: MessageType
payload: MessagePayload // this creates the problem
}

最佳答案

这就是 TypeScript 抛出错误的原因 - 它实际上试图做好事,但正确编码可能很棘手(相信我,I've been therealso there):

// so let's say we have:
const msg: IBotMsg = ...

// if we write
msg.payload.text // it fails because msg could be equal to {payload:{url:'...'}}
msg.payload.url // it fails because msg could be equal to {payload:{text:'...'}}
// so TypeScript prevents that and throws an error.

// You have to make clear to TypeScript that you know which properties you expect, either using typegards:
if ('text' in msg.payload) {
msg.payload.text;
}

// ... or by casting:
const msg2: {payload: TextPayload} = (msg as {payload: TextPayload});
msg2.payload.text; // no error
msg2.payload.url; // rightful error

实时查看此代码 in the TS playground

关于node.js - 如何正确使用 TypeScript 联合类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56876111/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com