gpt4 book ai didi

javascript - 如何在 JavaScript 中表示代数数据类型和模式匹配

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

在像 OCaml 这样的函数式语言中,我们有模式匹配。例如,我想记录用户在我网站上的操作。一个 Action 可以是 1) 访问一个网页,2) 删除一个项目,3) 检查另一个用户的个人资料等。在 OCaml 中,我们可以这样写:

type Action = 
| VisitPage of string (* www.myweb.com/help *)
| DeletePost of int (* an integer post id *)
| ViewUser of string (* a username *)

但是,我不确定如何在 JavaScript 中定义此 Action。我能想到的一种方式是

var action_1 = { pageVisited: "www.myweb.com/help", postDeleted: null, userViewed: null }
var action_2 = { pageVisited: null, postDeleted: 12345, userViewed: null }
var action_3 = { pageVisited: null, postDeleted: null, userViewed: "SoftTimur" }

但是这个结构体并没有表示pageVisitedpostDeleteduserViewed在其中是排他的。

谁能提出在 JavaScript 中更好地表示这种类型?

在 JavaScript 或 TypeScript 中是否有一种通用的模式匹配方法?

最佳答案

你想要一个 discriminated union ,TypeScript 通过添加具有不同字符串文字值的公共(public)属性来支持它,如下所示:

type VisitPage = { type: 'VisitPage', pageVisited: string }
type DeletePost = { type: 'DeletePost', postDeleted: number }
type ViewUser = { type: 'ViewUser', userViewed: string }

type Action = VisitPage | DeletePost | ViewUser

Action 类型由 type 属性区分,当您检查其类型时,TypeScript 将自动执行控制流分析以缩小 Action 的范围类型 属性。这是您获得模式匹配的方式:

function doSomething(action: Action) {
switch (action.type) {
case 'VisitPage':
// action is narrowed to VisitPage
console.log(action.pageVisited); //okay
break;
case 'DeletePost':
// action is narrowed to DeletePost
console.log(action.postDeleted); //okay
break;
case 'ViewUser':
// action is narrowed to ViewUser
console.log(action.userViewed); //okay
break;
default:
// action is narrowed to never (bottom),
// or the following line will error
const exhausivenessWitness: never = action; //okay
throw new Error('not exhaustive');
}
}

请注意,如果您愿意,您可以添加详尽检查,因此如果您向Action 联合添加另一种类型,像上面这样的代码会给您一个编译时警告。

希望对您有所帮助;祝你好运!

关于javascript - 如何在 JavaScript 中表示代数数据类型和模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47543329/

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