I've been struggling to figure out how to prevent an object from being added to an array based on a property value in generics.
During an online interview, I was given an exercise to create a zoo scenario within an hour:
There are five animals in the zoo, along with two birds. Two zookeepers work at night and four in the morning. Only Norman is allowed to enter the tiger's cage.
I started working on the exercise but got stuck in index.ts where I'm able to assign handlers to animals, but I want TypeScript to restrict this assignment based on certain conditions.
You can view the sandbox for this exercise at: 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);
}
}
}
In app.js:
I want typescript to prevent me from adding John to the 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)