Reputation: 21
Have an implementation of polymorphism in typescript.
enum empType {
developer = '1',
qa = '2',
manager = '3'
}
interface IEmployee {
type: empType;
ID: string;
name: string;
projectId: string;
}
interface IEmployeeDeveloper extends IEmployee {
type: empType.developer;
featureID: string;
deadline: string;
}
interface IEmployeeQa extends IEmployee {
type: empType.qa;
bugCount: number;
}
interface IEmployeeManager extends IEmployee {
type: empType. manager;
reporteeIDs: string[];
}
If I need to have a config data holding a list of such employees
let employees: Record<string, IEmployee> = {
'tom': {
type: empType.developer,
ID: '1',
name: 'tom',
projectId: '123',
featureID: 'xxx',
deadline: '01/01/2023'
},
'sham': {
type: empType.qa,
ID: '12',
name: 'sham',
projectId: '123',
bugCount: 10000
},
'harry': {
type: empType.manager,
ID: '3',
name: 'harry',
projectId: '123',
reporteeIDs: ['1', '2']
},
}
While trying to compile the code, I am getting such error.
⨯ Unable to compile TypeScript:
error TS2322: Type '{ type: empType.developer; ID: string; name: string; projectId: string; featureID: string; deadline: string; }' is not assignable to type 'IEmployee'.
Object literal may only specify known properties, and 'featureID' does not exist in type 'IEmployee'.
featureID: 'xxx',
~~~~~~~~~~~~~~~~
error TS2322: Type '{ type: empType.qa; ID: string; name: string; projectId: string; bugCount: number; }' is not assignable to type 'IEmployee'.
Object literal may only specify known properties, and 'bugCount' does not exist in type 'IEmployee'.
bugCount: 10000,
~~~~~~~~~~~~~~~
error TS2322: Type '{ type: empType.manager; ID: string; name: string; projectId: string; reporteeIDs: string[]; }' is not assignable to type 'IEmployee'.
Object literal may only specify known properties, and 'reporteeIDs' does not exist in type 'IEmployee'.
reporteeIDs: ['1', '2'],
~~~~~~~~~~~~~~~
If instead we try to initialize like this
let employees: Record<string, any> = /same config code as above/
Then I am able to compile. However I want my variables to be properly typed and I do not prefer using any in my type definition.
Another way is
let employees: Record<string, IEmployee | IEmployeeDeveloper | IEmployeeQa | IEmployeeManager> = /same config code as above/
The issue with this is that in near future I will create many types of IEmployee. Then I will have to change the type of employees everytime I do such a thing. Also need to update all those place where I am using this variables.
How can we handle such scenarios in typescript.
Upvotes: 2
Views: 240
Reputation: 1374
Here is how you can do it using Union Types. Read more here
type EmployeeItem = IEmployeeDeveloper | IEmployeeQa | IEmployeeManager;
let employees: Record<string, EmployeeItem> = {
'tom': {
type: empType.developer,
ID: '1',
name: 'tom',
projectId: '123',
featureID: 'xxx',
deadline: '01/01/2023'
},
'sham': {
type: empType.qa,
ID: '12',
name: 'sham',
projectId: '123',
bugCount: 10000
},
'harry': {
type: empType.manager,
ID: '3',
name: 'harry',
projectId: '123',
reporteeIDs: ['1', '2']
},
}
Upvotes: 3