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

如何基于对象属性创建TypeScript类型并确保类型与属性校验?

问题描述

现有如下对象数组:

const formTest = [
   { label: "test", name: "grossSalary" },
   { label: "test", name: "privatePension" },
];

希望基于数组中所有name属性构建一个类型,最终生成如下结果:

type FormValues = {
  grossSalary: string;
  privatePension: string;
}

要求该类型能严格校验属性,例如以下代码因包含不存在的invalidProperty,应当触发TypeScript错误:

const initialValues: FormValues = {
   grossSalary: "",
   invalidProperty: "",
}

尝试使用映射类型实现:

type FormValues = {
   [K in typeof formTest[number]["name"]]: string;
}

但该方式仅校验属性类型,不会对额外属性报错,请问该如何解决?

解决方案

核心问题有两个:一是原数组formTest的类型被TypeScript推断为宽泛的string集合,而非具体的字符串字面量;二是TypeScript默认的结构类型兼容规则允许对象字面量存在额外属性。要实现严格校验,需按以下步骤处理:

1. 将数组转为只读字面量类型

通过as const断言,强制TypeScript把数组中name属性的值识别为具体的字符串字面量,而非通用的string类型:

const formTest = [
   { label: "test", name: "grossSalary" },
   { label: "test", name: "privatePension" },
] as const;

2. 构建严格校验的类型

这里提供两种可行方案:

方案一:添加never类型索引签名禁止额外属性

给映射类型追加一个匹配所有字符串键的索引签名,将其类型设为never,这样任何不在name集合中的属性都会触发类型错误:

type FormValues = {
   [K in typeof formTest[number]["name"]]: string;
} & {
   [key: string]: never;
};

此时定义包含invalidProperty的initialValues,TypeScript会报错:类型“string”不能赋值给类型“never”,严格拦截额外属性。

方案二:使用satisfies运算符(TypeScript 4.9+)

若不想修改FormValues的类型结构,可在变量赋值时用satisfies运算符做严格校验:

type FormValues = {
   [K in typeof formTest[number]["name"]]: string;
};

const initialValues = {
   grossSalary: "",
   invalidProperty: "",
} satisfies FormValues; // 此处直接报错,提示额外属性不存在

这种方式更灵活,仅在赋值阶段做校验,不改变原类型的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:10:17