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

TypeScript如何定义返回函数集合中函数执行结果的函数类型

问题解答

核心原因

你遇到的类型问题本质是TypeScript泛型约束的设计逻辑导致的:

  • 泛型的extends约束仅代表最低匹配要求,而非对泛型的精确类型限制:
    你定义的T extends Partial<Record<ProductName, () => any>>只要求T中属于ProductName枚举范围内的属性为可选的无参函数,但并没有限制T不能包含ProductName之外的额外属性,这些额外属性的类型可以是任意值(比如字符串、数字等非函数类型)。

因此在泛型定义阶段,TypeScript无法100%确认T[keyof T]一定是函数类型——因为keyof T包含了所有T的键,其中可能存在非ProductName范围的键,对应的值不是函数。

为什么变量a的类型可以正确推导

当你实际调用onAnyProduct函数时,传入的是一个没有额外属性的对象字面量,TypeScript会根据你传入的实参做精确的类型推断:
此时T的类型被精确推导为{ product1: () => string, product2: () => {} },T的键只有product1和product2,对应的值都是函数,因此ReturnType<T[keyof T]>可以正确计算为string | {},再加上可选链带来的undefined,最终a的类型就是string | {} | undefined。

修复方案

如果要让TypeScript在泛型定义阶段就识别T[keyof T]是函数类型,可以调整泛型定义,限制T的键只能是ProductName的子集:

export function onAnyProduct<K extends ProductName, T extends Record<K, () => any>>(
    productCallbacks: T
): ReturnType<T[K]> | undefined {
    const name = detectProduct() as K;
    const callback = productCallbacks[name];
    return callback?.();
}

调整后泛型K被限制为ProductName的子集,T的键只能是K范围内的值,所有属性都符合函数类型,T[K]必然是函数类型,不会再出现类型问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:24:05