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

TypeScript:为嵌套返回对象实现嵌套输入对象键的自动补全

问题:工厂函数返回值的类型自动补全失效

我要创建一个工厂函数,接收配置参数后返回带自动补全能力的对象。功能已经实现,但返回值的部分类型自动补全不正常。

期望效果

const result = createSomething({
  apis: {
    foo: { baseURL: "http://localhost:3000" },
    bar: { baseURL: "http://localhost:3001" },
  },
});

// foo 和 bar 应触发自动补全,且类型为`AxiosInstance`
result.apis.foo
result.apis.bar

当前失效的实现

我知道Object.entries处理时会丢失类型信息,试过类型断言但没解决。原本以为keyof typeof config.apis能满足,但自动补全的键只被识别为string类型:

const createSomething = (config: {
  apis: Record<string, CreateAxiosDefaults>;
}) => {
  const apis = Object.entries(config.apis).reduce(
    (acc, [apiKey, axiosConfig]) => {
      acc[apiKey] = axios.create(axiosConfig);
      return acc;
    },
    {} as Record<keyof typeof config.apis, AxiosInstance>
  );

  return {
    apis,
  };
};

能实现补全但无法批量处理的方案

下面的代码能实现自动补全,但没法批量把Axios配置映射为实例:

const createSomething = (config: {
  apis: Record<string, CreateAxiosDefaults>;
}) => {
  return {
    apis: {
      foo: axios.create(),
      bar: axios.create()
    }
  };
};

有没有替代Object.entries的方案能保留类型信息?输入和输出结构必须不变,实际场景里还有更多字段要保留。


解决方案

问题核心是你用了Record<string, CreateAxiosDefaults>作为apis的类型,这会让TypeScript丢失具体的键名信息。要保留自动补全,需要用泛型捕获传入apis的具体结构,而非宽泛的Record类型。

修改后的实现代码

import axios, { CreateAxiosDefaults, AxiosInstance } from 'axios';

const createSomething = <T extends Record<string, CreateAxiosDefaults>>(config: {
  apis: T;
}) => {
  // 定义映射类型:将T的每个值类型从配置转为Axios实例
  type ApiInstances = {
    [K in keyof T]: AxiosInstance;
  };

  const apis = Object.entries(config.apis).reduce((acc, [apiKey, axiosConfig]) => {
    acc[apiKey as keyof T] = axios.create(axiosConfig);
    return acc;
  }, {} as ApiInstances);

  return {
    apis,
    // 保留原配置中的其他字段
    ...config
  };
};

关键说明

  1. 泛型捕获具体结构:<T extends Record<string, CreateAxiosDefaults>>让TypeScript自动推导传入apis的具体键名和结构,而非将其视为普通字符串键对象。
  2. 映射类型匹配输出:ApiInstances通过遍历keyof T,把每个键对应的类型从CreateAxiosDefaults转为AxiosInstance,完美匹配输出结构。
  3. 类型断言消除报错:apiKey as keyof T告知TypeScript当前遍历的键是T的合法键,避免类型不兼容报错。

效果验证

调用函数时,TypeScript会自动补全result.apis下的foo、bar等键,且它们的类型均为AxiosInstance,同时支持批量处理任意数量的API配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:35:33