You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript联合类型疑问:Fish|Birds为何可赋值空对象?

TypeScript联合/交叉类型的keyof规则及常见疑问

先给大家明确两个核心规则,这是理解后续示例的基础:

  • keyof (A | B) 等价于 (keyof A) & (keyof B) —— 联合类型的keyof结果是两个类型key的交集
  • keyof (A & B) 等价于 (keyof A) | (keyof B) —— 交叉类型的keyof结果是两个类型key的并集

几个直观的正常示例

1. 联合类型只能访问公共字段

当两个接口有公共方法/字段时,它们的联合类型实例只能安全调用公共部分:

interface Bird { fly(): void; layEggs(): void; }
interface Fish { swim(): void; layEggs(): void; }
declare function getSmallPet(): Fish | Bird;
let pet = getSmallPet(); 
pet.layEggs(); // ✅ 完全没问题,因为不管是Bird还是Fish都有layEggs方法
// pet.fly(); ❌ 这里会报错,因为pet可能是Fish,根本没有fly方法

2. 交叉类型必须包含所有字段

交叉类型是把多个类型合并成一个,所以赋值的时候得把所有类型的字段都带上:

interface Birds { flys: boolean; layEggs: string; }
interface Fish { swim: number; layEggs: string; }
declare let k: Fish & Birds;
k = { flys:true, layEggs:"", swim:3} // ✅ 完美符合,包含了两个接口的所有必填字段
// k = { layEggs:"" } ❌ 不行,缺了flys和swim,不符合交叉类型的要求

3. 用类型别名验证keyof结果

直接看类型别名的推导结果,能更清晰理解keyof的规则:

interface Bird { fly: number; layEggs: string; }
type g1 = keyof Bird; // 推导结果:"fly" | "layEggs"
interface Fish { swim: boolean; layEggs: string; }
type g2 = keyof Fish; // 推导结果:"swim" | "layEggs"
type PetALL= keyof( Bird & Fish ); // 推导结果:"fly" | "swim" | "layEggs"(交叉类型keyof是并集)
type Pet = keyof( Bird | Fish ); // 推导结果:"layEggs"(联合类型keyof是交集)

让人困惑的异常示例解答

先看这段代码:

interface Birds { flys: boolean; layEggs: string; }
interface Fish { swim: number; layEggs: string; }
declare let k: Fish | Birds;
k = {}; // 疑问:为啥允许赋值空对象?按说至少得有{ layEggs: "" }吧?

这其实是TypeScript结构类型系统和严格模式开关共同导致的结果:

核心原因

TypeScript默认是宽松类型检查模式(没开启strict: true),在这种模式下,它允许你赋值一个“不完整”的对象给联合类型——它并不会强制要求你立刻补全所有必填字段,默认假设你后续会给对象添加缺失的属性。

但如果你开启了strict: true(这也是官方推荐的生产环境配置),这段代码会直接报错:

// 开启strict: true后
k = {}; // ❌ 报错提示:类型 '{}' 缺少Fish类型要求的'swim'和'layEggs',或者缺少Birds类型要求的'flys'和'layEggs'

本质逻辑

从类型安全角度看,空对象{}其实并不符合Fish或Birds的任何一个类型结构(都缺必填字段),但宽松模式下TypeScript放松了检查。严格模式下则会严格校验:赋值给联合类型的值,必须能匹配联合类型中至少一个完整类型的结构。

所以如果想要避免这种“不安全”的赋值,直接在tsconfig.json里把strict设为true就好啦。

内容的提问来源于stack exchange,提问作者Alexander Yelich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:27:49