【问题标题】:Typescript prevent objects being added to array of objects if an object's boolean property is true如果对象的布尔属性为真,Typescript 会阻止将对象添加到对象数组中
【发布时间】:2020-09-14 14:58:38
【问题描述】:

我已尝试找到解决方案,但我似乎无法找出如何在泛型中防止对象被包含在基于属性值的数组中。

我在一次在线面试中得到了以下练习,我应该在一个小时内开发以下内容:

一个动物园,里面有五只动物和两只鸟,两个动物园管理员过夜,四个动物园管理员早上。只有诺曼人可以进入虎笼

我开始研究它,但卡在 index.ts 中,我可以在其中执行以下操作: Lion.assignHandler(约翰); 但我希望打字稿阻止我将约翰添加到狮子,而不是让我。我只希望 norman 和其他在 lion's handlers 中的员工,并且只允许 _dangerHandler 属性为 true 的 handlers 员工。

沙盒位于以下位置:https://codesandbox.io/s/zoo-example-yi3op

export default interface Dangerous {
    canBeHandledBy(employees: Employee[]): void;
}

import Employee from "./Employee";

export default class Animal {
    private _handlers: Employee[] = [];
    constructor(private _name: string){}
    public get name() {
        return this._name;
    }
    public get handlers(): Employee[] {
        return this._handlers;
    }
    public set handlers(employees: Employee[]) {
        this._handlers = employees;
    }
    public assignHandler(employee: Employee): void {
        this._handlers.push(employee);
    }
}

export default class Employee {
    constructor(private _name: string, private _gender: Gender, private _employeeTitle: EmployeeTitle, private _dangerHandler: boolean = false) {}
    public get name():string {
        return this._name;
    }
    public get gender(): Gender {
        return this._gender;
    }
    public get isDangerHandler(): boolean {
        return this._dangerHandler;
    }
    public get title(): EmployeeTitle {
        return this._employeeTitle;
    }
    public set title(title: EmployeeTitle){
        this._employeeTitle = title;
    }
}


export default class Lion extends Animal implements Dangerous {
    constructor(_name: string) {
        super(_name)
    }
    
    canBeHandledBy(employees: Employee[]): void {        
        try {
            const ordinaryEmployees = employees.filter(emp => !emp.isDangerHandler);
            if(ordinaryEmployees.length >0 ){
                throw new Error('Ordinary meployees not allowed to handle Lion');
            }
            this.handlers = employees;
        }
        catch(e) {
            console.log(e);
        }
    }
}

在 app.js 中

我希望 typescript 阻止我将 john 添加到 lion 而不是它让我。

const norman:Employee = new Employee("norman", Gender.MALE, EmployeeTitle.ZOOKEEPER, true);
const john:Employee = new Employee("john", Gender.MALE, EmployeeTitle.ZOOKEEPER);

const lion = new Lion("zumba");
lion.assignHandler(john)

【问题讨论】:

    标签: typescript oop generics


    【解决方案1】:

    我已经简化了您的示例,但您可以从以下建模中获得灵感,看看它是否适合您:

    type TypeOfAnimal = 'Dangerous' | 'Harmless'
    
    interface Animal<T extends TypeOfAnimal> {
      name: string
      assignHandler: (handler: Employee<T>) => void
    }
    
    class Lion implements Animal<'Dangerous'> {
      constructor(readonly name: string) {}
      assignHandler(handler: Employee<'Dangerous'>) {
        console.log(handler)
      }
    }
    
    class Employee<T extends TypeOfAnimal> {
      constructor(readonly name: string, readonly canHandle: T) {}
    }
    
    const norman = new Employee('Norman', 'Dangerous')
    const john = new Employee('John', 'Harmless')
    
    const lion: Lion = new Lion('Zumba')
    
    lion.assignHandler(norman) // compiles
    lion.assignHandler(john) // does not compile
    
    

    【讨论】:

    • 感谢 Pritam,这正是我想看到的,我真的很感激。谢谢
    • 乐于助人:)
    • 虽然现在我无法将它添加到动物园任何动物,但还是有问题。 ` class Zoo { private _animals: Array> = [];构造函数(私有_name:字符串){} public addAnimal(动物:Animal):void { this._animals.push(animal); } } const lion: Lion = new Lion('Zumba') lion.assignHandler(norman) // 编译 const zoo = new Zoo('Georgia Zoo'); zoo.addAnimal(狮子); `
    【解决方案2】:

    您可以简单地在Animal.ts 中更新assignhandler() 以检查传递到方法中的employee 是否将isDangerHandler 属性设置为True

    public assignHandler(employee: Employee): void {
      if (employee.isDangerHandler) {
        this._handlers.push(employee);
      }
    }
    

    【讨论】:

    • 那么在泛型中我们是否无法检查属性是否将实例添加到对象数组中并且打字稿可以看到该对象上的属性设置为true。我想要的是打字稿不允许我添加将 isDangerHandler 设置为 true 的员工对象
    • Generics 可以帮助您防止添加错误的type,从而确保您的代码是type-safe。在您的示例中,isDangerHandlerattribute,而generics 不处理attributes
    • 谢谢codemax,我明白你在说什么,现在我明白了。
    猜你喜欢
    • 2022-01-16
    • 2019-12-27
    • 2015-11-15
    • 2015-09-21
    • 2021-03-22
    • 1970-01-01
    • 2022-01-13
    • 2018-09-06
    相关资源
    最近更新 更多