简体   繁体   English

将javascript关联数组转换为打字稿

[英]Converting javascript associative array to typescript

In one of our systems, we have a lot of UI related javascript that handles menu actions and that look like below 在我们的系统之一中,我们有很多与UI相关的javascript,它们可以处理菜单操作,如下所示

var menuActions = {
    "edit-profile": {
        Title: "rs_edit_profile",
        Action: function(callback){
            //some logic here to handle the UI
        },
        HasPermission: true
    },
    "delete-profile": {
        Title: "rs_edit_profile",
        Action: function(callback){
            //some logic here to handle the UI
        },
        HasPermission: true
    },
    "create-profile": {
        Title: "rs_edit_profile",
        Action: function(callback){
            //some logic here to handle the UI
        },
        HasPermission: false
    }

} }

and that is used with switch / if cases like if(menuAction[actionName] === "edit profile")... which then calls the menuActions[actionName].Action() . 和用于与switch / if情况下,像if(menuAction[actionName] === "edit profile")...然后调用menuActions[actionName].Action()

We're converting the system to TypeScript right now, which is all new for us, and I'm stuck on how I best should re-organize and convert this specific piece of code. 我们现在正在将系统转换为TypeScript,这对我们来说是全新的,我一直在坚持最好的方式来重新组织和转换这段特定的代码。

I don't like how it's done with javascript right now, so if possible, I would like to take the opportunity to change it to something better while doing the conversion to typescript. 我现在不喜欢使用javascript进行操作,因此,如果可能的话,我想借此机会将其更改为更好的字体,同时进行打字稿转换。

My intuition says I should have a collection of MenuAction instances from a class, but I'm not sure as to how I would implement that and then use it. 我的直觉说我应该从一个类中收集MenuAction实例,但是我不确定如何实现并使用它。

Should I completely omit the use of a class and instead just use normal objects in an array? 我是否应该完全省略类的使用,而只在数组中使用普通对象?

(It might help to know that this is code for an Angular 1.X view controller). (这可能有助于知道这是Angular 1.X视图控制器的代码)。

Just regarding the typing, this is one way you could do it: 就打字而言,这是您可以做到的一种方式:

type Action = {
    Title: string;
    Action: (cb: () => void) => void;
    HasPermission: boolean;
}

var menuActions: {[key:string]: Action} = {
    "edit-profile": {
        Title: "rs_edit_profile",
        Action: function (callback) {
            //some logic here to handle the UI
        },
        HasPermission: true
    },
    "delete-profile": {
        Title: "rs_edit_profile",
        Action: function (callback) {
            //some logic here to handle the UI
        },
        HasPermission: true
    },
    "create-profile": {
        Title: "rs_edit_profile",
        Action: function (callback) {
            //some logic here to handle the UI
        },
        HasPermission: false
    }
}

Whether or not to use class instances is up to you, TS is quite agnostic about design choices like that. 是否使用类实例取决于您,TS对于这样的设计选择是完全不可知的。

... and if you want the type to be usable for classes to implement , you have to define it as an interface instead. ...,如果您希望该类型可用于类的implement ,则必须将其定义为接口。 It's really no other difference between a custom type ( type alias ) and an interface. 自定义类型( 类型别名 )和接口之间确实没有其他区别。

interface Action {
    Title: string;
    Action: (cb: () => void) => void;
    HasPermission: boolean;
}

How about something like this: 这样的事情怎么样:

class MenuAction {
    private id: string;
    private title: string;
    private hasPermission: boolean;
    private action: (cb: Function) => void;

    constructor(id: string, title: string, hasPermission: boolean, action: (cb: Function) => void) {
        this.id = id;
        this.title = title;
        this.hasPermission = hasPermission;
        this.action = action;
    }

    get Title() {
        return this.title;
    }

    get HasPermission() {
        return this.hasPermission;
    }

    get Action() {
        return this.action;
    }

    equals(id: string): boolean {
        return this.id === id;
    }
}

const actions = [
    new MenuAction("edit-profile", "rs_edit_profile", true, function(callback) {
        //some logic here to handle the UI
    }),
    new MenuAction("delete-profile", "rs_edit_profile", true, function(callback) {
        //some logic here to handle the UI
    }),
    new MenuAction("create-profile", "rs_edit_profile", false, function(callback) {
        //some logic here to handle the UI
    })
];

function execute(id: string, callback: Function) {
    actions.filter(action => action.equals(id)).forEach(action => {
        action.Action(callback);
    });
}

( code in playground ) 操场上的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM