'I want to designate a type according to the conditions of the object property
There is organizational data with a hierarchical structure.
Organizational nodes are divided into Root, Dept, and User.
The object property type is assigned a type suitable for node data.
So, I hope that the node interface suitable for the object type will be attached conditionally.
To solve this problem, I tried Index Types and Conditional Types, but they were not successful.
Any help would be appreciated🙇♂️
export enum NodeType {
root = "root",
dept = "dept",
user = "user",
}
interface Node {
readonly nodeId: string;
readonly type: NodeType;
title: string;
childNodes?: Node[];
}
interface RootNode extends Node {
type: NodeType.root;
childNodes?: (DeptNode | UserNode)[];
}
interface DeptNode extends Node {
type: NodeType.dept;
childNodes?: (DeptNode | UserNode)[];
deptId: string;
companyCode: string;
}
interface UserNode extends Node {
type: NodeType.user;
childNodes?: UserNode[];
employeeNumber: string;
userPrincipalName: string;
}
/**
* from hierarchy data to flatting data
*/
function flatting(st: Node) {
flatCompanyData.push(st);
if (st.childNodes) {
st.childNodes.forEach((x) => flatting(x));
}
}
const companyData: RootNode = {
nodeId: "0",
type: NodeType.root,
title: "Company 1",
childNodes: [
{
nodeId: "0.0",
type: NodeType.dept,
title: "Department 1",
deptId: "A1",
companyCode: "557",
childNodes: [
{
nodeId: "0.0.0",
type: NodeType.user,
title: "User 1",
employeeNumber: "201911",
userPrincipalName: "[email protected]",
},
{
nodeId: "0.0.1",
type: NodeType.user,
title: "User 2",
employeeNumber: "201912",
userPrincipalName: "[email protected]",
},
],
},
{
nodeId: "0.1",
type: NodeType.dept,
title: "Department 2",
deptId: "A2",
companyCode: "558",
},
],
};
let flatCompanyData: Node[] = [];
flatting(companyData);
// I want to be the type of DeptNode interface because the type of object property is NodeType.dept.
const selectDept = flatCompanyData.filter((x) => x.type === NodeType.dept);
selectDept.forEach((x) => {
console.log({
nodeId: x.nodeId,
type: x.type,
title: x.title,
// The type is not affirmed in the node that fits the object property type, so you have to affirm the type yourself.
deptId: (x as DeptNode).deptId,
companyCode: (x as DeptNode).companyCode,
});
});
// I want to be the type of UserNode interface because the type of object property is NodeType.user.
const selectUser = flatCompanyData.filter((x) => x.type === NodeType.user);
selectUser.forEach((x) => {
console.log({
nodeId: x.nodeId,
type: x.type,
title: x.title,
// The type is not affirmed in the node that fits the object property type, so you have to affirm the type yourself.
employeeNumber: (x as UserNode).employeeNumber,
userPrincipalName: (x as UserNode).userPrincipalName,
});
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|