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

如何让TypeScript拒绝包含特定字段的对象?

如何在TypeScript中强制函数参数不包含指定字段?

我需要实现一个TypeScript类型,确保传入函数的对象完全不包含指定的字段(比如UserDao中的email、_id等),只有额外字段的对象才合法。

现有代码如下:

type UserDao = {
  _id: string;
  email: string;
  authCode: number;
  authCodeExpirationDate: Date;
  createdAt: Date;
  updatedAt: Date;
};

export type OnlyAdditionalFieldsUser<TUser> = Omit<TUser, keyof UserDao>;

function getUserObject<TUser>(
  user: OnlyAdditionalFieldsUser<TUser>
) {
  return user;
}

type TestUser = {
  email: string;
  firstname: string;
  lastname: string;
};

const user: TestUser = { email: 'test@test.com', firstname: 'John', lastname: 'Doe' };

console.log(getUserObject<TestUser>(user)); // 期望TypeScript报错,但实际没有

问题所在

当前的Omit<TUser, keyof UserDao>只是移除了指定字段的类型声明,但并没有禁止对象实际携带这些字段——TypeScript会忽略这些“额外”的字段,不会触发错误。

需要明确:我的需求和“禁止额外属性”的场景不同,我是要主动拒绝存在指定字段的对象,而非限制对象只能有预定义属性。另外,变量层面用satisfies可以实现校验,但我需要在函数参数层面完成这个限制。

解决方案

核心思路是:在Omit的基础上,给所有禁止字段添加never类型的约束——因为never类型没有合法取值,相当于强制这些字段不能存在。

修改后的代码:

type UserDao = {
  _id: string;
  email: string;
  authCode: number;
  authCodeExpirationDate: Date;
  createdAt: Date;
  updatedAt: Date;
};

// 定义禁止的字段集合
type ForbiddenFields = keyof UserDao;

// 核心类型:移除禁止字段的类型,同时强制这些字段不能存在
export type OnlyAdditionalFieldsUser<TUser> = Omit<TUser, ForbiddenFields> & {
  [K in ForbiddenFields]?: never;
};

function getUserObject<TUser>(
  user: OnlyAdditionalFieldsUser<TUser>
) {
  return user;
}

type TestUser = {
  email: string;
  firstname: string;
  lastname: string;
};

const user: TestUser = { email: 'test@test.com', firstname: 'John', lastname: 'Doe' };

console.log(getUserObject<TestUser>(user)); // 现在TypeScript会报错:属性"email"的类型不兼容

优化泛型推断

如果不想手动指定泛型参数,可以调整函数的泛型约束,让TypeScript自动推断并校验:

function getUserObject<T extends OnlyAdditionalFieldsUser<T>>(
  user: T
) {
  return user;
}

// 直接调用即可触发报错
console.log(getUserObject(user));

原理说明

Omit<TUser, ForbiddenFields>负责保留允许的字段类型,而& { [K in ForbiddenFields]?: never; }则添加了一个冲突约束:所有禁止字段要么不存在,要么类型必须是never(没有合法值)。当传入的对象包含禁止字段时,TypeScript会检测到类型冲突,从而抛出错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:07:40