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

如何从接口属性值推导或约束另一属性的类型?

TypeScript接口约束:从predicates推导defaultOperation的类型

要实现defaultOperation严格约束为predicates的键名,你需要调整接口的泛型设计,让TypeScript能明确关联两者的类型。以下是两种可行方案:

方案1:显式指定键的联合类型

将接口设计为接受两个泛型参数:数据类型T和键类型K(string的子类型),直接把defaultOperation的类型绑定到K:

export interface IFilterConfig<T, K extends string> {
  readonly predicates: Record<K, (value: T) => boolean>;
  readonly defaultOperation: K;
}

// 实现类时显式声明键的联合类型
export class SomeClass implements IFilterConfig<string, 'key1' | 'key2'> {
  predicates = {
    key1: (data: string) => false,
    key2: (data: string) => true,
  };
  defaultOperation = 'key1'; // 合法
  // defaultOperation = 'key3'; // 编译报错:'"key3"'无法分配给'"key1" | "key2"'
}

方案2:泛型类自动推导类型

把类定义为泛型类,让TypeScript根据传入的predicates自动推导defaultOperation的合法值:

export interface IFilterConfig<T, P extends Record<string, (value: T) => boolean>> {
  readonly predicates: P;
  readonly defaultOperation: keyof P;
}

export class SomeClass<T, P extends Record<string, (value: T) => boolean>> implements IFilterConfig<T, P> {
  predicates: P;
  defaultOperation: keyof P;

  constructor(predicates: P, defaultOperation: keyof P) {
    this.predicates = predicates;
    this.defaultOperation = defaultOperation;
  }
}

// 使用时自动推导类型
const filterInstance = new SomeClass(
  {
    key1: (data: string) => false,
    key2: (data: string) => true,
  },
  'key1' // 编译通过
  // 'key3' // 编译报错:'"key3"'无法分配给'"key1" | "key2"'
);

原方案失效原因

你之前的接口定义中,实现类SomeClass implements IFilterConfig<string>未传递泛型参数P,TypeScript会默认将P推断为Record<string, (value:string)=>boolean>,此时keyof P等价于string,导致defaultOperation可以接受任意字符串,无法起到约束作用。只有通过显式指定泛型参数,或让类的泛型自动推导P的具体结构,才能让keyof P对应到predicates的实际键名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:18:21