Sof*_*mur 1 javascript ocaml object pattern-matching typescript
在像OCaml这样的函数式语言中,我们有模式匹配.例如,我想在我的网站上记录用户的操作.一个动作可以是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 *)
Run Code Online (Sandbox Code Playgroud)
但是,我不确定如何Action在JavaScript中定义它.我能想象的一种方式是
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" }
Run Code Online (Sandbox Code Playgroud)
但是这种结构并没有表达出来pageVisited,postDeleted并且userViewed在它们中是排他性的.
任何人都可以在JavaScript中提出更好的代表吗?
有没有在JavaScript或TypeScript中进行模式匹配的常用方法?
你想要一个有区别的联合,TypeScript支持通过添加一个具有不同字符串文字值的公共属性,如下所示:
type VisitPage = { type: 'VisitPage', pageVisited: string }
type DeletePost = { type: 'DeletePost', postDeleted: number }
type ViewUser = { type: 'ViewUser', userViewed: string }
type Action = VisitPage | DeletePost | ViewUser
Run Code Online (Sandbox Code Playgroud)
该Action类型由判别type属性,和打字原稿将自动执行控制流分析,以缩小的Action时检查它的type性能.这是模式匹配的方式:
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');
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您愿意,可以添加详尽的检查,因此,如果您要向Action联合添加其他类型,则上述代码将为您提供编译时警告.
希望有所帮助; 祝好运!
函数式编程中的类型可以用类来模拟:
class Action {}
class VisitPage extends Action {
constructor(pageUrl){
super();
this.pageUrl = pageUrl;
}
}
class ViewUser extends Action {
constructor(userName){
super();
this.userName = userName;
}
}
var myAction = new VisitPage("http://www.google.com");
console.log(myAction instanceof Action);
console.log(myAction.pageUrl);Run Code Online (Sandbox Code Playgroud)
对于模式匹配:
class Action {}
class VisitPage extends Action {
constructor(pageUrl){
super();
this.pageUrl = pageUrl;
}
}
class ViewUser extends Action {
constructor(userName){
super();
this.userName = userName;
}
}
function computeStuff(action){
switch(action.constructor){
case VisitPage:
console.log(action.pageUrl); break;
case ViewUser:
console.log(action.userName); break;
default:
throw new TypeError("Wrong type");
}
}
var action = new ViewUser("user_name");
var result = computeStuff(action);Run Code Online (Sandbox Code Playgroud)