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

如何强制TypeScript泛型仅包含指定属性,禁止额外属性?

解决TypeScript中FormFields嵌套对象的严格属性约束问题

你当前的问题核心在于T extends FormFields是结构兼容检查——只要T满足FormFields的最小结构要求,额外属性不会被限制。要实现嵌套对象仅允许value和error两个属性,需要做精确类型匹配,以下是具体方案:

方案1:使用Exact工具类型实现严格匹配

定义一个Exact工具类型,通过双向extends检查确保两个类型结构完全一致,而非单向兼容:

// 精确类型匹配工具
type Exact<T, U> = T extends U 
  ? U extends T 
    ? T 
    : never 
  : never;

// 原FormFields接口保留
interface FormFields {
    [key: string]: {
        value: string;
        error: boolean;
    };
}

// 修改泛型函数的约束为Exact<T, FormFields>
const getFormFields = <T extends Exact<T, FormFields>>(formFields: T) => formFields;

方案2:直接约束属性为严格类型

如果不想额外定义工具类型,也可以直接把嵌套对象的类型抽离,再通过泛型约束强制每个属性与该类型完全匹配:

// 定义严格的字段类型,无扩展空间
type StrictFormField = { value: string; error: boolean };

// 泛型约束T的所有属性必须严格等于StrictFormField
const getFormFields = <T extends { [K in keyof T]: StrictFormField }>(
  formFields: T extends Record<keyof T, StrictFormField> ? T : never
) => formFields;

验证效果

  • 合法示例(无额外属性,正常通过):
const validForm = getFormFields({
  username: { value: "john_doe", error: false },
  email: { value: "", error: true }
});
  • 非法示例(存在额外属性,TypeScript报错):
// 报错:类型"{ value: string; error: boolean; extra: string; }"不能赋值给类型"StrictFormField"
const invalidForm = getFormFields({
  username: { value: "john_doe", error: false, extra: "invalid" }
});

原理说明

两种方案的核心都是通过双向类型检查替代单向的extends:

  • 单向extends只要求T包含FormFields的必要属性,允许额外扩展;
  • 双向检查则强制T的结构与目标类型完全一致,任何额外属性都会触发类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:12:24