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

TypeScript泛型类读取泛型键映射类型时报错求助

解决泛型联合类型映射的索引类型不匹配问题

问题核心在于TypeScript无法在泛型上下文中将value.type的类型收窄为T['type']的具体成员,而是将其推断为宽泛的string类型,导致与myMap的键类型不匹配。以下是三种可行的解决方案:

方案1:将getValue改为泛型方法,直接接收type参数

跳过整个实例,直接传入类型标识,让TypeScript明确索引的键类型:

type A = { type: 'a'; };
type B = { type: 'b'; };
type C = A | B;

type UnionType = { type: string; };
class MyClass<T extends UnionType> {
    private myMap: { [type in T['type']]?: Extract<T, { type: type }> } = {};    

    setValue(type: T['type'], value: Extract<T, { type: typeof type }>) {
        this.myMap[type] = value;
    }

    getValue<K extends T['type']>(type: K): Extract<T, { type: K }> | undefined {
        return this.myMap[type];
    }
}

// 使用示例
const cls = new MyClass<C>();
cls.setValue('a', { type: 'a' });
const aVal = cls.getValue('a'); // 类型自动推断为A | undefined

方案2:保留接收实例的方式,添加泛型约束与类型断言

如果必须接收整个T类型的实例作为参数,通过泛型约束绑定实例的type属性,再用断言帮助TypeScript完成类型推断:

type A = { type: 'a'; };
type B = { type: 'b'; };
type C = A | B;

type UnionType = { type: string; };
class MyClass<T extends UnionType> {
    private myMap: { [type in T['type']]?: Extract<T, { type: type }> } = {};    

    setValue(type: T['type'], value: Extract<T, { type: typeof type }>) {
        this.myMap[type] = value;
    }

    getValue<V extends T>(value: V): Extract<T, { type: V['type'] }> | undefined {
        return this.myMap[value.type as V['type']];
    }
}

// 使用示例
const cls = new MyClass<C>();
const aInstance = { type: 'a' } as A;
cls.setValue('a', aInstance);
const fetchedVal = cls.getValue(aInstance); // 类型自动推断为A | undefined

方案3:优化UnionType定义,从根源强制类型收窄

修改UnionType的type属性定义,让TypeScript将其识别为字符串字面量类型而非宽泛的string,避免类型推断偏差:

type A = { type: 'a'; };
type B = { type: 'b'; };
type C = A | B;

// 用string & {}让TypeScript将type识别为字面量类型
type UnionType = { type: string & {}; };
class MyClass<T extends UnionType> {
    private myMap: { [type in T['type']]?: Extract<T, { type: type }> } = {};    

    setValue(type: T['type'], value: Extract<T, { type: typeof type }>) {
        this.myMap[type] = value;
    }

    getValue(value: T): Extract<T, { type: typeof value.type }> | undefined {
        // 此时value.type会被正确推断为T['type']的成员,无需额外断言
        return this.myMap[value.type];
    }
}

你可以根据实际业务场景选择最合适的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:35:56