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

如何为Person类型实现类型安全的DisabledKeys映射对象类型扩展?

解决TypeScript嵌套对象的类型安全禁用键集合问题

这个问题确实很常见——当需要为嵌套对象创建对应的禁用键集合时,既要保证类型安全,又要避免冗余和不同步的问题。咱们一步步来解决它:

首先先明确基础类型(把Passport抽出来,方便后续维护和复用):

type Passport = { series: string; number: string };
type Person = {
  email: string;
  name: string;
  passport: Passport;
};

为什么原来的实现有问题?

你最初的交叉类型写法存在两个核心缺陷:

  1. 允许额外属性:交叉类型{ [key in keyof Person]?: boolean } & { ... }会放松类型限制,导致像foo: number这种不属于Person的键也能通过编译
  2. 缺乏自动同步:当Person中的passport属性重命名时,DisabledKeys里的passport键不会触发编译错误,导致类型定义和原类型不同步

正确的类型安全实现方案

我们可以创建一个递归映射类型,它会遍历原类型的每个属性,同时支持嵌套对象的禁用键定义,并且严格限制只能使用原类型的键:

// 递归生成嵌套的禁用键类型
type NestedDisabled<T> = {
  [K in keyof T]?: boolean | (T[K] extends object ? NestedDisabled<T[K]> : never);
};

// 基于Person生成严格的禁用键类型
type DisabledKeys = NestedDisabled<Person>;

这个类型的核心特性

  • 严格限制键范围:只能使用Person中存在的键(email、name、passport),添加任何额外键都会直接触发编译错误
  • 自动同步属性名:如果Person中的passport重命名为idCard,DisabledKeys里的对应键也会自动更新,旧的passport键会立即报错,保证类型同步
  • 支持两种禁用方式:
    • 对于普通属性(比如email、name),可以直接设为boolean表示是否禁用
    • 对于嵌套对象属性(比如passport),既可以设为boolean(禁用整个嵌套对象),也可以传入嵌套的禁用键对象(比如{ series: true }表示只禁用passport.series)

合法使用示例

// 合法:禁用email,以及passport的series字段
const validDisabledKeys: DisabledKeys = {
  email: true,
  passport: { series: true }
};

// 合法:禁用整个passport对象
const validDisabledKeys2: DisabledKeys = {
  passport: true
};

非法示例(会触发编译错误)

// 错误:'foo'不属于Person的键
const invalidKeys1: DisabledKeys = { foo: 123 };

// 错误:如果Person的passport已重命名为idCard,这里的passport键不存在
const invalidKeys2: DisabledKeys = { passport: { series: true } };

可选:严格模式(禁止直接把嵌套对象设为boolean)

如果你希望嵌套对象必须明确指定内部的禁用键,不能直接设为boolean,可以调整递归类型:

type NestedDisabledStrict<T> = {
  [K in keyof T]?: T[K] extends object ? NestedDisabledStrict<T[K]> : boolean;
};

type DisabledKeysStrict = NestedDisabledStrict<Person>;

这样passport只能传入嵌套对象,不能直接写passport: true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:08:40