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

如何创建仅接受可选或数组类型的TypeScript映射类型?

解决方案:约束对象属性为可选原始类型或原始类型数组

首先明确核心需求:对象的属性只能是可选原始类型(Primitive | undefined)或原始类型数组(Primitive[]),严格禁止必填的原始类型。你之前的写法失效是因为(Primitive | undefined) | Primitive[]包含了纯Primitive类型,无法排除必填原始属性的情况。

实现代码

type Primitive = number | string | boolean | object | symbol;

// 定义允许的属性类型范围
type AllowedProp = Primitive[] | (Primitive | undefined);

// 双重约束:确保属性属于允许范围,且禁止必填原始类型
type ValidSelectorProps<T> = 
  // 第一步:限定所有属性必须是允许的类型
  { [K in keyof T]: AllowedProp } & 
  // 第二步:检查属性是否为必填原始类型,是则返回never触发错误
  { [K in keyof T]: T[K] extends Primitive ? undefined extends T[K] ? unknown : never : unknown };

// 用于验证类型的示例函数
function processSelector<T>(props: ValidSelectorProps<T>): T {
  return props as T;
}

验证效果

兼容合法类型(对应你的T1)

// 显式包含undefined的属性,合法
const validProps1 = {
  a: true as boolean | undefined,
  b: {} as Object | undefined,
  c: ['foo', 'bar'] as string[]
};
processSelector(validProps1);

// 可选属性(自动隐含undefined),合法
const validProps2 = {
  a?: boolean,
  b?: Object,
  c: ['foo'] as string[]
};
processSelector(validProps2);

拦截非法类型(对应你的T2)

// 报错:属性a是必填的boolean(纯原始类型),不符合约束
const invalidProps = {
  a: true,
  b: ['test'] as string[] | undefined
};
processSelector(invalidProps);

原理说明

  1. AllowedProp先圈定属性的可选范围:要么是原始类型数组,要么是带undefined的原始类型。
  2. 第二个交叉类型通过条件判断,对每个属性做二次校验:如果属性类型是纯Primitive且不包含undefined,则返回never,直接触发TypeScript类型错误,从而禁止必填原始类型的属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 02:34:53