面试题-合并类型
你的理解存在一些偏差。在 TypeScript 中,联合类型(A | B
) 和 交叉类型(A & B
) 的行为是不同的:
正确分析
1. 联合类型(A | B
)
表示值可以是 A
或 B
,但不需要同时满足两者。
type A = { name: string };
type B = { age: number; sex: string };
type C = A | B; // C 可以是 A 或 B// 合法示例
const c1: C = { name: "Alice" }; // 符合 A
const c2: C = { age: 25, sex: "male" }; // 符合 B(注意:你之前的例子缺少 sex)// 错误示例
const invalid: C = { age: 25 }; // 错误!B 要求必须有 sex 属性
2. 交叉类型(A & B
)
表示值必须 同时满足 A
和 B
的所有属性。
type C = A & B; // C 必须同时有 name、age 和 sex// 合法示例
const c3: C = { name: "Bob", age: 30, sex: "male" };// 错误示例
const invalid: C = { name: "Bob", age: 30 }; // 缺少 sex 属性
你的代码问题
你定义的 C
是 A | B
,但示例中的 c2
和 c3
存在问题:
c2
:{ age: 25 }
不满足B
的要求(B
需要age
和sex
)。c3
:{ name: "Bob", age: 30, sex: "male" }
在A | B
中是合法的,但这是因为它恰好同时满足A
和B
,而不是因为联合类型允许合并属性。
总结
类型 | 要求 | 示例 | |
---|---|---|---|
**`A | B`** | 只需符合 A 或 B | { name: "Alice" } 或 { age: 25, sex: "male" } |
A & B | 必须同时符合 A 和 B | { name: "Bob", age: 30, sex: "male" } |
修正后的代码:
type A = { name: string };
type B = { age: number; sex: string };// C 是 A 或 B
type C = A | B; // 合法示例
const c1: C = { name: "Alice" }; // 符合 A
const c2: C = { age: 25, sex: "male" }; // 符合 B// 错误示例(之前的问题)
// const c2: C = { age: 25 }; // 错误:缺少 sex
// const c3: C = { name: "Bob", age: 30 }; // 错误:如果是 B 则缺少 sex
如果需要合并属性,应该使用 交叉类型(A & B
)。