将javascript关联数组转换为typescript

Converting javascript associative array to typescript

本文关键字:typescript 转换 数组 javascript 关联      更新时间:2023-09-26

在我们的一个系统中,我们有很多与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
    }

}

,用于switch/if情况,如if(menuAction[actionName] === "edit profile")...然后调用menuActions[actionName].Action()

我们现在正在将系统转换为TypeScript,这对我们来说都是全新的,我被如何最好地重新组织和转换这段特定的代码所困扰。

我不喜欢现在用javascript完成的方式,所以如果可能的话,我想趁这个机会在转换到typescript的同时把它改变成更好的东西。

我的直觉说我应该从一个类的MenuAction实例的集合,但我不确定我将如何实现,然后使用它。

我应该完全省略类的使用,而只是在数组中使用普通对象吗?

(知道这是Angular 1的代码可能会有帮助。

关于输入,有一种方法可以这样做:

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
    }
}

是否使用类实例取决于你,TS对这样的设计选择是相当不可知的。

…如果您希望该类型可用于implement的类,则必须将其定义为接口。自定义类型(类型别名)和接口之间实际上没有其他区别。

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

这样如何:

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)