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

如何无需新建类型从TypeScript已有类型生成指定键白名单类型?

TypeScript 基于已有类型实现白名单属性约束(无需新建类型)

问题描述

我有如下TypeScript类型:

interface Koko {
  a?: string,
  b?: number, 
  c?: string[],
  d?: number[]
}

希望基于该类型实现仅允许使用a、b键的白名单约束:传入c或d时触发类型检查错误,传入符合类型的a或b时通过检查,最终效果等价于手动定义如下类型:

interface PartialKoko {
  a?: string,
  b?: number, 
}

请问是否可以无需新建类型实现该需求?

实现方案

可以实现,核心是利用TypeScript的类型组合特性,通过Pick、Exclude和Record类型的组合,在变量声明或函数参数中直接施加约束,无需单独定义新类型。

方案1:变量声明时直接约束

在声明变量时,通过类型交集同时提取允许的属性、禁止多余属性:

const validObj: Pick<Koko, 'a' | 'b'> & Record<Exclude<keyof Koko, 'a' | 'b'>, never> = {
  a: 'hello',
  b: 789
};

// 以下写法会触发类型错误
// const invalidObj: Pick<Koko, 'a' | 'b'> & Record<Exclude<keyof Koko, 'a' | 'b'>, never> = {
//   c: ['test']
// };
  • Pick<Koko, 'a' | 'b'>:提取Koko中a、b两个属性的可选类型
  • Record<Exclude<keyof Koko, 'a' | 'b'>, never>:将Koko中除a、b外的c、d键约束为never类型,一旦赋值就会触发类型检查错误

方案2:泛型函数约束(适合参数校验)

如果需要在函数参数中应用该约束,可以写一个泛型函数,直接在参数类型中组合约束逻辑:

function onlyAllowAB<T extends Pick<Koko, 'a' | 'b'> & Record<Exclude<keyof Koko, 'a' | 'b'>, never>>(obj: T) {
  return obj;
}

// 合法调用,无错误
onlyAllowAB({ a: 'valid' });
onlyAllowAB({ b: 100 });

// 非法调用,触发类型错误
// onlyAllowAB({ c: ['invalid'] });
// onlyAllowAB({ a: 'ok', d: [1, 2] });

这种方式不需要提前定义PartialKoko类型,直接通过泛型和类型组合实现了白名单属性的校验逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:42:56