如何为TypeScript树形节点正确定义互斥的size或children属性类型?
TypeScript树形节点类型的互斥约束实现
要实现叶子节点和含子节点的节点之间的互斥约束,你可以通过联合类型将两种节点类型明确区分开,各自定义必填属性并禁止对方的专属属性:
// 叶子节点:必须有size,禁止children属性 type LeafNode = { name: string; size: number; children?: never; // 明确标记children不能被赋值 }; // 父节点:必须有children,禁止size属性 type ParentNode = { name: string; children: Node[]; size?: never; // 明确标记size不能被赋值 }; // 最终的Node类型是两种节点的联合 type Node = LeafNode | ParentNode;
约束效果说明
- 叶子节点必须包含
name和size,不能添加children属性(哪怕赋值undefined也会触发类型报错); - 父节点必须包含
name和children,不能添加size属性; - 任何不符合这两种结构的对象都会在编译阶段被TypeScript检测出来。
示例验证
// ✅ 合法叶子节点 const textFile: Node = { name: "README.md", size: 2048 }; // ✅ 合法父节点 const docsFolder: Node = { name: "docs", children: [textFile] }; // ❌ 非法:同时包含size和children const invalidNode1: Node = { name: "test", size: 100, children: [] }; // ❌ 非法:叶子节点缺少size const invalidNode2: Node = { name: "empty-file" }; // ❌ 非法:父节点缺少children const invalidNode3: Node = { name: "empty-folder" };
这种方式通过类型分支明确了节点的两种互斥形态,比原有的可选属性约束更严谨,能提前拦截不符合业务规则的代码。
内容的提问来源于stack exchange,提问作者Joji
相关产品推荐
相关产品推荐

