作为js开发者如何使用typescript

作为js开发者如何使用typescript

本文将提出一些建议关于js开发者如何使用typescript

1. switch 和 对象遍历

switch语法在多个编程语言中经常使用。但是,作为一个前端开发者,我们会更希望使用对象遍历去查找。

为什么?有了switch语句,我们就有了一个程序性的控制流,并且在每个情况下都不得不使用中断。如果我们可能忘记处理就可能会导致错误或意想不到的行为。

而对于对象遍历来说有更自然的控制流,更容易维护,也有更好的可读性。

handleAction(type: ActionType, task: Task): void {
    switch(type) {
        case ActionType.NEW_TASK:
            this.taskService.createTask(task);
            break;
        case ActionType.EDIT_TASK:
            this.taskService.editTask(task);
            break;
        case ActionType.REMOVE_TASK:
            this.taskService.removeTask(task);
            break;
        case ActionType.COMPLETE_TASK:
            this.taskService.completeTask(task);
            break;
        default:
            throw Error(`handleAction: taskActionType ${type} is not supported`);
    }
}

对象遍历查找会是更直观的方法。这些操作结构良好,更易于扩展。

handleAction(type: ActionType, task: Task): void {
    const actions = <Record<ActionType, (task: Task) => Promise<void>>>{
        [ActionType.NEW_TASK]: (task: Task) =>
            this.taskService.createTask(task),
        [ActionType.EDIT_TASK]: (task: Task) =>
            this.taskService.editTask(task),
        [ActionType.REMOVE_TASK]: (task: Task) =>
            this.taskService.removeTask(task),
        [ActionType.COMPLETE_TASK]: (task: Task) =>
            this.taskService.completeTask(task),
    };
    if (actions[type]) {
        void actions[type](task);
    } else {
        throw Error(`handleAction: taskActionType ${type} is not supported`);
    }
}

2. map 和 对象

我们都很熟悉js中的map方法:

const taskLabelMap = new Map([
    [ActionType.NEW_TASK, 'Create Task'],
    [ActionType.EDIT_TASK, 'Edit Task'],
    [ActionType.REMOVE_TASK, 'Remove Task'],
    [ActionType.COMPLETE_TASK, 'Complete Task'],
]);

在粗略看上面代码就是发现有点难以维护、定义。有时,开发人员忘记了在typescript中定义map有一种更简单的方法,即对象遍历。更自然的是使用给定的js特点,而不是typescript引入的数据结构。

const taskLabelMap1: {[key: string]: string} = {
    [ActionType.NEW_TASK]: 'Create Task',
    [ActionType.EDIT_TASK]: 'Edit Task',
    [ActionType.REMOVE_TASK]: 'Remove Task',
    [ActionType.COMPLETE_TASK]: 'Complete Task',
}

3. enum和对象及字符串联合

js中没有enum。

因此,使用enum与使用对象相反。那么,有什么区别呢?enum还有一些额外的功能。与对象相反,这些值不能被重新分配不同的值。

因此,为了类型安全,对象通常与enum一起使用:

export enum ActionType {
    NEW_TASK = 'new',
    EDIT_TASK = 'edit',
    REMOVE_TASK = 'remove',
    COMPLETE_TASK = 'complete',
}

下面的示例使用了enum的特性。这些值是类型安全的,但可能没有显式地将这些值与enum一样使用。

const taskActions = <const>{
    NEW_TASK: 'CREATE',
    EDIT_TASK: 'EDIT',
    REMOVE_TASK: 'REMOVE',
    COMPLETE_TASK: 'COMPLETE',
};
type TASK_ACTIONS = (typeof taskActions)[keyof typeof taskActions];

因此,除枚举之外,最好的选择是结合类声明的联合类型。这些值是类型安全的,可以像引用枚举一样引用。

const newTask = ActionType.NEW_TASK

type TASK_ACTION = 'CREATE' | 'EDIT' | 'REMOVE' | 'COMPLETE';
export class TaskActions {
    NEW_TASK: TASK_ACTION = 'CREATE';
    EDIT_TASK: TASK_ACTION = 'EDIT';
    REMOVE_TASK: TASK_ACTION = 'REMOVE';
    COMPLETE_TASK: TASK_ACTION = 'COMPLETE';
}

4. for循环和reduce

js中有很多可以操作数组的方法。因此,每个前端开发人员都应该熟悉它们。然而,开发人员通常使用不同的方法来实现基本任务。在下面的示例中,应该检索具有特定类别的任务的数量。

我们可以使用for循环,如下所示:

let taskHomeCount = 0;
for (const task of tasks) {
    if (task.category === TaskCategroy.HOME) {
        taskHomeCount += 1;
    }
}

不过,作为js开发者我们可以使用reduce方法。reduce可以很容易地将数组转换为所有类型的对象。这是一个非常强大的功能。

return taskHomeCount = tasks.reduce((result: number, task: Task) => {
    return task.category === TaskCategory.HOME ? ++result : result;
}, 0);

你可能感兴趣的:(javascript,typescript)