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

TypeScript如何校验值匹配指定类型且不丢失原有推导类型

方案1:使用 TS 4.9+ 内置的 satisfies 操作符(推荐)

这个操作符就是为该场景设计的,作用是仅校验值是否符合目标类型的要求,不会覆盖值本身的类型推导,用法如下:

const fruitMenu = <const>{
    "apple": "pie",
    "banana": "split",
    "strawberry": "ice",
} satisfies Record<string, string>;

// 正常推导为 "apple" | "banana" | "strawberry"
type Fruits = keyof typeof fruitMenu;
// 正常推导为 "pie" | "split" | "ice"
type FoodTypes = typeof fruitMenu[Fruits];

function getFoodType(fruit: Fruits): FoodTypes {
    return fruitMenu[fruit];
}

// 错误示例:定义阶段直接触发类型错误,提示数字键/值不符合要求
const fruitMenu2 = <const>{
    "apple": "pie",
    "banana": "split",
    "strawberry": "ice",
    0: 2,
} satisfies Record<string, string>;

方案2:低版本TS兼容的泛型工具函数

如果你的项目使用的TS版本低于4.9,可以通过一个通用的泛型函数实现完全相同的效果:

// 通用类型校验工具函数,仅做类型校验不修改原始推导类型
const satisfiesType = <T,>() => <U extends T>(value: U) => value;

// 先绑定要校验的目标类型 Record<string, string>
const checkStringRecord = satisfiesType<Record<string, string>>();
const fruitMenu = checkStringRecord(<const>{
    "apple": "pie",
    "banana": "split",
    "strawberry": "ice",
});

// 类型推导效果和方案1完全一致
type Fruits = keyof typeof fruitMenu;
type FoodTypes = typeof fruitMenu[Fruits];

两种方案均满足需求:

  • 定义对象阶段自动校验是否符合指定类型要求,非法结构直接抛出类型错误
  • 完全保留值本身的字面量类型,不会被拓宽为声明的通用类型
  • 不需要重复编写任何键名、类型定义,符合DRY原则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:06:03