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

如何限制TypeScript的keyof仅接受值类型为指定类型的键?

实现TypeScript泛型键筛选:仅保留值类型匹配指定类型的键

要实现仅筛选出对象类型T中值类型为F的键,我们可以通过条件映射类型改造Key泛型类型,具体实现如下:

interface Data {
  items: string[];
  name: string;
}

// 改造后的Key类型:仅保留T中值类型属于F的键
type Key<T, F> = {
  [K in keyof T]: T[K] extends F ? K : never;
}[keyof T] & string;

interface TextField<T> {
  input: 'text';
  // 限定key对应T中的值为string类型
  key: Key<T, string>;
}

interface ArrayField<T> {
  input: 'array';
  // 限定key对应T中的值为数组类型(用unknown[]适配任意数组)
  key: Key<T, unknown[]>;
}

type Field<T> = TextField<T> | ArrayField<T>;

// ✅ 正确示例:无报错,key类型与input类型匹配
const validConfig: Field<Data>[] = [
  {
    input: 'text',
    key: 'name' // name对应string类型,符合TextField要求
  },
  {
    input: 'array',
    key: 'items' // items对应string[]类型,符合ArrayField要求
  }
];

// ❌ 错误示例:触发类型报错,key与input类型不匹配
const invalidConfig: Field<Data>[] = [
  {
    input: 'text',
    key: 'items' // items是数组类型,不符合TextField的string要求
  },
  {
    input: 'array',
    key: 'name' // name是string类型,不符合ArrayField的数组要求
  }
];

核心逻辑说明

  1. Key泛型的实现:

    • 通过映射类型{ [K in keyof T]: ... }遍历T的所有键
    • 对每个键K,用条件类型T[K] extends F ? K : never判断值类型是否匹配F:匹配则保留键名K,否则设为never
    • 最后通过[keyof T]索引访问,提取所有非never的键,得到符合条件的键的联合类型,再与string交叉确保结果仅为字符串键
  2. TextField与ArrayField的约束:

    • TextField<T>指定Key<T, string>,确保key对应的T属性值是string类型
    • ArrayField<T>指定Key<T, unknown[]>,适配任意数组类型(如果需要严格限定数组元素类型,可以替换为string[]等具体类型)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:32:37