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

TypeScript 泛型函数中恢复「对象字面量仅允许已知属性」校验的方法

原理说明

TypeScript 的「对象字面量多余属性校验」属于针对直接赋值场景的语法糖校验,并非结构类型系统的强制规则。当对象字面量先传入泛型函数时,TypeScript 会优先将对象字面量的全量属性(包含多余属性)推导为泛型参数的实际类型,经过转换后的返回值属于目标类型的子类型,结构类型系统默认允许子类型赋值给父类型,因此不会触发多余属性校验。

改造方案

核心思路是利用 TypeScript 的上下文类型推导能力,给泛型函数新增一个默认推导的泛型参数,承接返回值接收方的目标类型,将入参中不在目标类型上的属性标记为never类型,只要传入多余属性就会触发类型报错,变相恢复多余属性校验能力。

1. 恒等函数identity改造示例

declare function setUser(arg: {name: string}): void;

// 改造后的identity
declare function identity<T, Expected = T>(
  v: T extends Expected ? T & Record<Exclude<keyof T, keyof Expected>, never> : never
): T;

setUser({name: 'a', age: 12}); // 报错,符合预期
setUser(identity({name: 'a', age: 12})); // 现在会报错,符合预期
const u = {name: 'a', age: 12};
setUser(u); // 无报错,属于已知的规则例外,符合预期

2. 自定义NullableToOptional转换函数改造示例

declare function setUser(arg: {name: string}): void;

type NonNullable<T> = T extends null ? never : T;
export type NullableToOptional<T> = {
    [K in keyof T]: null extends T[K] ? NonNullable<T[K]> | undefined : T[K];
};

// 改造后的toOptional函数
export function toOptional<T, Expected = T>(
  x: T extends Expected ? T & Record<Exclude<keyof T, keyof Expected>, never> : never
): NullableToOptional<T> {
    return x as NullableToOptional<T>;
}

setUser({name: 'a', age: 12}); // 报错,符合预期
setUser(toOptional({name: 'a', age: 12})); // 现在会报错,符合预期
注意事项

该改造方案的校验行为和原生多余属性校验完全对齐:如果泛型函数的返回值没有直接传入明确类型的参数/变量,而是先赋值给未显式标注类型的临时变量,上下文类型推导失效,不会触发多余属性校验,该表现和原生的const u = {name: 'a', age:12}; setUser(u)不报错的逻辑一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:45:00