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

TypeScript动态筛选类实例的类型推导问题

解决TypeScript中getInstance函数的类型推导问题

问题背景

现有类A、B及对应的类型谓词函数isA、isB,用这些谓词函数筛选混合实例数组时,TypeScript能正确推导结果类型:

class A { }
class B { }

const isA = (x: any): x is A => {
    return x instanceof A;
};

const isB = (x: any): x is B => {
    return x instanceof B;
};

const arr: Array<A | B> = [new A(), new A(), new B()]

const onlyA = arr.filter(isA) // 类型:A[]
const onlyB = arr.filter(isB) // 类型:B[]

需求目标

实现getInstance()函数:

  • 接收包含"a"和/或"b"的字符串数组
  • 返回对应名称的类实例数组,类型推导需符合预期:
    • getInstance(["a"])返回类型为A[](与onlyA一致)
    • getInstance(["a","b"])返回类型为(A | B)[]

现有实现的问题

尝试通过对象关联字符串与谓词函数,泛型约束为对象键,但类型推导失效,且存在逻辑错误:

const Obj = {
    a: isA,
    b: isB
}

const getInstance = <T extends keyof typeof Obj>(types: T[]) => {
    const fns = types.map(type => Obj[type])
    const set = fns.map(fn => arr.filter(() => fn)) // 逻辑错误:未正确使用谓词函数作为筛选条件

    return set.flat(1) 
}

const retA = getInstance(["a"]) // 错误推导为(A | B)[],预期为A[]
const retAB = getInstance(["a", "b"]) // 预期为(A | B)[]

解决方案

步骤1:优化对象类型推断

给关联对象加上as const,让TypeScript保留更精确的键值类型关联;

步骤2:定义键到实例类型的映射

通过条件类型提取谓词函数对应的实例类型;

步骤3:修正筛选逻辑并指定返回类型

直接使用谓词函数作为filter的回调,同时明确函数返回类型,让TypeScript正确推导结果。

完整代码:

class A { }
class B { }

const isA = (x: any): x is A => {
    return x instanceof A;
};

const isB = (x: any): x is B => {
    return x instanceof B;
};

const arr: Array<A | B> = [new A(), new A(), new B()]

// 加上as const让TypeScript推断精确的键值类型关联
const Obj = {
    a: isA,
    b: isB
} as const;

// 定义键到对应实例类型的映射类型
type KeyToInstance<K extends keyof typeof Obj> = 
  typeof Obj[K] extends (x: any) => x is infer T ? T : never;

const getInstance = <T extends keyof typeof Obj>(types: T[]): KeyToInstance<T>[] => {
    const result: KeyToInstance<T>[] = [];
    for (const type of types) {
        // 直接使用谓词函数作为筛选条件
        result.push(...arr.filter(Obj[type]));
    }
    return result;
};

const retA = getInstance(["a"]) // 类型:A[](符合预期)
const retAB = getInstance(["a", "b"]) // 类型:(A | B)[](符合预期)

关键说明

  • as const确保Obj的键值类型不会被宽泛推断,TypeScript能准确关联"a"对应isA、"b"对应isB;
  • KeyToInstance类型通过条件类型提取谓词函数的类型断言结果(即目标实例类型);
  • 循环筛选并合并结果的方式,既修正了原代码的逻辑错误,也让TypeScript能清晰推导返回数组的元素类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:32:10