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

为含函数对象的容器创建包装函数的TypeScript类型错误排查

解决方法

核心问题是TypeScript无法在函数内部自动关联泛型参数T、U与post${U}方法的类型关系,需要通过类型断言或辅助类型定义帮编译器理清类型关联。

方案1:类型断言快速修复

直接对调用的方法进行类型断言,明确它符合参数和返回值的类型要求:

class APIContainer {
    api1!: API1;
    api2!: API2;
}

class API1 {
    postA(x: string): string { return '' }
    postB(x: number): number { return 1 }
    patchA(x: string): string { return '' }
}

class API2 {
    postX(x: string): string { return '' }
    postY(x: number): number { return 1 }
    patchX(x: string): string { return '' }
}

type ExtractPostMethods<T> = T extends `post${infer V}` ? V : never;

function doCall<T extends keyof APIContainer, U extends ExtractPostMethods<keyof APIContainer[T]>>(
    api: T, 
    entity: U, 
    data: Parameters<APIContainer[T][`post${U}`]>[0]
): ReturnType<APIContainer[T][`post${U}`]> {
    const container = new APIContainer();
    // 断言方法类型,让编译器确认这是符合要求的函数
    const method = container[api][`post${entity}`] as (data: Parameters<APIContainer[T][`post${U}`]>[0]) => ReturnType<APIContainer[T][`post${U}`]>;
    return method(data);
}

const result = doCall('api1', 'A', '1');
result.length; // 类型推断正常,返回string

方案2:重构辅助类型增强类型关联

通过定义映射类型,提前梳理API容器的post方法结构,让TypeScript更清晰地跟踪类型:

class APIContainer {
    api1!: API1;
    api2!: API2;
}

class API1 {
    postA(x: string): string { return '' }
    postB(x: number): number { return 1 }
    patchA(x: string): string { return '' }
}

class API2 {
    postX(x: string): string { return '' }
    postY(x: number): number { return 1 }
    patchX(x: string): string { return '' }
}

// 定义所有可用的post方法映射:{ [API键]: { [方法后缀]: (参数) => 返回值 } }
type APIPostMethods = {
    [K in keyof APIContainer]: {
        [M in ExtractPostMethods<keyof APIContainer[K]>]: APIContainer[K][`post${M}`]
    }
};

function doCall<K extends keyof APIPostMethods, M extends keyof APIPostMethods[K]>(
    api: K,
    entity: M,
    data: Parameters<APIPostMethods[K][M]>[0]
): ReturnType<APIPostMethods[K][M]> {
    const container = new APIContainer();
    return container[api][`post${entity as string}`](data);
}

const result = doCall('api1', 'A', '1');
result.length; // 类型推断正常

原代码报错原因

泛型参数T和U在外部调用时能正确推断,但函数内部编译器无法确认container[api][post${entity}]的类型与Parameters/ReturnType定义的类型完全匹配——模板字符串类型的拼接在泛型上下文中无法被编译器自动关联,因此需要手动辅助类型关联或断言。

内容的提问来源于stack exchange,提问作者Bart van den Burg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 16:27:49