gpt4 book ai didi

typescript 嵌套标记/区分联合类型

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

假设我有以下类型(语法是 Elm-ish/Haskell-ish):

type Reply = LoginReply | LogoutReply
type LoginReply = LoginSucceeded | AlreadyLoggedIn String

如果我尝试使用 Typescript 的可区分联合对其进行建模,我将面临这样的问题,即 LoginReply 需要具有值为“loginReply”的属性 kind 但它可以不是因为它是使用 type 关键字而不是 class 声明的。

到目前为止,这是我解决问题的最佳方法:

type Reply = LoginReply | LogoutReply

type LoginReply = LoginSucceeded | AlreadyLoggedIn

interface LoginSucceeded {
kind: "loginSucceeded";
}

interface AlreadyLoggedIn {
kind: "alreadyLoggedIn";
loggedInUsername: string;
}

interface LogoutReply {
kind: "logoutReply";
}

如您所见,甚至不能在任何地方使用 "loginReply",因此不能用于歧视。

我知道 Reply 变量是 LoginReply 的唯一解决方法是查看它的 kind 是否是 之一” loginSucceeded""alreadyLoggedIn"

那么,我如何在 Typescript 中实现我想要的? 如何创建子类型本身为可区分联合类型的可区分联合类型?

最佳答案

因为 LoginReply 只是 LoginSucceeded | 的并集AlreadyLoggedIn,从类型系统的角度来看,type Reply = LoginReply | 没有区别LogoutReplytype Reply = LoginSucceeded |已经登录 |注销回复type 关键字引入了一个类型别名,顾名思义,它只是该类型的一个方便名称,它本身并不是一个新类型。

您有两个选择,但都不是您 100% 想要的。

您可以检查 LoginReply 的所有可能值 kind,正如您提到的那样:

function doStuff(o: Reply) {
switch(o.kind)
{
case 'alreadyLoggedIn' :
case 'loginSucceeded' :
o; /* is LoginReply */ break;
case 'logoutReply': o // o is LogoutReply
}
}

或者您可以为 LoginReply 子类型添加一个额外的 subKind 字段:

export type Reply = LoginReply | LogoutReply

type LoginReply = LoginSucceeded | AlreadyLoggedIn

interface LoginSucceeded {
subKind: "loginSucceeded";
kind: "loginReply";
}

interface AlreadyLoggedIn {
kind: "loginReply";
subKind: "alreadyLoggedIn";
loggedInUsername: string;
}

interface LogoutReply {
kind: "logoutReply";
logout: boolean
}

function doStuff(o: Reply) {
switch(o.kind)
{
case 'loginReply' : o // is LoginReply
switch(o.subKind) {
case 'alreadyLoggedIn' : o; /* is AlreadyLoggedIn */ break;
case 'loginSucceeded' : o; /* is LoginSucceeded */ break;
}
break;
case 'logoutReply': o // LogoutReply
}
}

关于 typescript 嵌套标记/区分联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51744218/

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