如何从接口属性值推导或约束另一属性的类型?
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
相关产品推荐
相关产品推荐

