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

如何为函数返回值实现TypeScript泛型映射类型?

解决TypeScript泛型函数调用对象方法后类型推导失效的问题

当你用泛型函数访问全局对象的属性并调用其返回的函数时,会遇到返回值类型推导失效的问题——明明定义了返回类型是对应Key的函数返回值,但TS却把它推断成所有可能返回值的联合类型,导致类型报错。

问题复现

const dict = {
  "foo": () => 1,
  "bar": () => "1"
} as const;

function getData<Key extends keyof typeof dict>(foobar: Key): ReturnType<typeof dict[Key]> {
  return dict[foobar](); // 报错:Type 'string | number' is not assignable to type 'ReturnType<{ readonly foo: () => number; readonly bar: () => string; }[Key]>'
}

而如果对象属性直接是值而非函数,类型推导就能正常工作:

const dict = { "foo": 1, "bar": "1" } as const;
function getData<Key extends keyof typeof dict>(foobar: Key): typeof dict[Key] {
  return dict[foobar]; // 正常推导,无报错
}

问题原因

TypeScript在这里无法自动把dict[foobar]()的返回值和ReturnType<typeof dict[Key]>做精确关联。dict[foobar]会被视为联合类型的函数((() => number) | (() => string)),调用后自然返回联合类型string | number,而泛型参数Key的具体类型没有被用来收窄这个联合类型的范围。

解决方案

方案1:类型断言(简单直接)

直接用类型断言告诉TS返回值的精确类型,这是最快的解决方式:

const dict = {
  "foo": () => 1,
  "bar": () => "1"
} as const;

function getData<Key extends keyof typeof dict>(foobar: Key): ReturnType<typeof dict[Key]> {
  return dict[foobar]() as ReturnType<typeof dict[Key]>;
}

方案2:预定义映射类型(更清晰)

预先定义一个映射类型,明确每个Key对应的返回值类型,让TS能更清晰地推导:

const dict = {
  "foo": () => 1,
  "bar": () => "1"
} as const;

type Dict = typeof dict;
// 定义每个Key对应的函数返回类型
type DictReturnTypes = { [K in keyof Dict]: ReturnType<Dict[K]> };

function getData<K extends keyof Dict>(foobar: K): DictReturnTypes[K] {
  return dict[foobar]() as DictReturnTypes[K];
}

方案3:函数重载(适合键较少的场景)

如果对象的键数量不多,可以用函数重载来明确每个参数对应的返回类型,这种方式不需要断言,类型最精确:

const dict = {
  "foo": () => 1,
  "bar": () => "1"
} as const;

// 重载签名
function getData(foobar: 'foo'): number;
function getData(foobar: 'bar'): string;
// 实现签名
function getData(foobar: keyof typeof dict) {
  return dict[foobar]();
}

验证效果

现在调用getData('foo')会自动推导返回类型为number,调用getData('bar')推导为string,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:16:12