satisfies 用于在不丢失键名和值字面量类型的前提下进行单向类型校验。它保留对象精确推导类型,支持 keyof 精确提取、智能补全与严格访问,同时校验值类型合法性,且拒绝多余字段;而 as 会覆盖类型、破坏精度。

用 satisfies 就是为了解决“既要类型检查,又不能丢掉具体键名和值类型”这个经典矛盾。它不改变推导结果,只做单向校验,所以对象的字面量键、精确值类型、方法可用性全都能保留。
让键名保持字面量类型,支持智能补全和严格访问
如果你直接用类型注解(比如 const obj: Record = { a: "x", b: "y" }),TS 会把 obj 当作泛型 Record 处理,keyof typeof obj 就变成 string,补全失效,拼写错误也检查不出来。
改用 satisfies:
- 对象仍按实际赋值内容推导出精确类型:
{ a: string; b: string } -
keyof typeof obj得到"a" | "b",调用obj.a有补全,obj.c直接报错 - 后续函数参数可精准约束,比如
(key: keyof typeof obj) => obj[key]
同时校验值类型,防止非法值混入
比如颜色配置要求每个值必须是合法的 RGB 字符串:
- 定义类型
type Rgb = `rgb(${number},${number},${number})` - 写对象时用
satisfies Record<string rgb></string>校验所有值 - 如果某项写成
"rgba(0,0,0,1)"或"red",编译期立刻报错 - 但对象本身类型仍是
{ red: string; green: string; ... },不是宽泛的Record<string rgb></string>
避免用 as,否则会破坏类型精度
as 是强制覆盖类型,会丢掉原始推导信息:
-
as Record后,obj类型变成泛型 Record,键名无法被精确捕获 - 甚至允许写
{ a: "x", b: "y", c: "z" }这种多余字段,因为as不校验结构是否超集 -
satisfies则相反:只接受子集或精确匹配,多一个键、少一个键、值类型不对,统统报错
配合 as const 做更细粒度的字面量控制
当值本身也是字面量(比如状态码、固定字符串)时,可以组合使用:
const status = { OK: 200, ERROR: 500 } as const satisfies Record<string number></string>- 此时
typeof status.OK是200(字面量数字),不是number -
keyof typeof status是"OK" | "ERROR",且值类型也精确 - 注意顺序:
as const要在satisfies前,否则as const会被忽略











