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

如何根据输入参数确定第三方函数的返回值类型?

问题与解决方案

问题背景

我正在对接一个第三方函数,它的返回类型标注为any(示例中实际定义为object),但真实返回结构完全由传入的outputParams参数决定。示例代码如下:

interface OutputParam {
  name: string;
}

// 第三方函数,无法修改
const executeStoredProc = (outputParams: OutputParam[]): object => {
  const retval = {};
  for (let output of outputParams) {
    retval[output.name] = 'sample data';
  }
  return retval;
}

const example = () => {
  const outputParams: OutputParam[] = [
    { name: "Sandwich_ID" },
    { name: "Sandwich_Has_Ketchup" },
  ];

  const exampleResult = executeStoredProc(outputParams);

  // 需求:让TypeScript识别exampleResult拥有Sandwich_ID和Sandwich_Has_Ketchup属性
  const sandwichId = exampleResult.Sandwich_ID; // 当前会报错:类型“object”上不存在属性“Sandwich_ID”
  const sandwichHasKetchup = exampleResult.Sandwich_Has_Ketchup; // 同上

  return {
    sandwichId,
    sandwichHasKetchup,
  };
};

我希望将exampleResult自动转换成与outputParams对应的类型,比如:

type ExampleOutput = {
  Sandwich_ID: unknown,
  Sandwich_Has_Ketchup: unknown,
}

解决方案

有两种可行的方式实现需求,一种是手动类型断言,另一种是利用TypeScript泛型自动推导类型,后者更灵活。

方法一:手动类型断言

如果outputParams的结构固定,可以先手动定义目标类型,再通过类型断言将函数返回值转为该类型:

// 先定义预期类型
type ExampleOutput = {
  Sandwich_ID: unknown;
  Sandwich_Has_Ketchup: unknown;
};

const example = () => {
  const outputParams: OutputParam[] = [
    { name: "Sandwich_ID" },
    { name: "Sandwich_Has_Ketchup" },
  ];

  // 断言返回值为目标类型
  const exampleResult = executeStoredProc(outputParams) as ExampleOutput;

  // 此时TypeScript能识别属性,不会报错
  const sandwichId = exampleResult.Sandwich_ID;
  const sandwichHasKetchup = exampleResult.Sandwich_Has_Ketchup;

  return {
    sandwichId,
    sandwichHasKetchup,
  };
};

这种方式简单直接,但缺点是如果outputParams的结构变化,需要同步修改ExampleOutput类型,维护成本较高。

方法二:泛型自动推导类型

通过封装一个泛型工具函数,让TypeScript自动根据outputParams的具体值推导返回类型,无需手动维护类型定义:

interface OutputParam {
  name: string;
}

// 第三方函数,无法修改
const executeStoredProc = (outputParams: OutputParam[]): object => {
  const retval = {};
  for (let output of outputParams) {
    retval[output.name] = 'sample data';
  }
  return retval;
}

// 封装泛型函数,自动推导返回类型
const executeStoredProcTyped = <T extends readonly OutputParam[]>(
  outputParams: T
): { [K in T[number]['name']]: unknown } => {
  // 类型断言兼容第三方函数的参数类型
  return executeStoredProc(outputParams as OutputParam[]) as { [K in T[number]['name']]: unknown };
};

const example = () => {
  // 使用as const将数组转为只读元组,让TypeScript捕获每个name的具体字符串值
  const outputParams = [
    { name: "Sandwich_ID" },
    { name: "Sandwich_Has_Ketchup" },
  ] as const;

  // 调用封装后的函数,返回类型自动推导为对应的结构
  const exampleResult = executeStoredProcTyped(outputParams);

  // TypeScript自动识别属性,支持代码提示,不会报错
  const sandwichId = exampleResult.Sandwich_ID;
  const sandwichHasKetchup = exampleResult.Sandwich_Has_Ketchup;

  return {
    sandwichId,
    sandwichHasKetchup,
  };
};

原理说明:

  1. 使用as const将outputParams转为只读元组,TypeScript会保留每个元素name的具体字符串字面量类型(而不是宽泛的string类型)。
  2. 泛型T捕获这个只读元组的类型,通过T[number]['name']提取所有name的字面量集合。
  3. 利用映射类型{ [K in T[number]['name']]: unknown }生成与outputParams对应的返回类型,属性名就是name的值,属性类型设为unknown(如果知道返回值的具体类型,可替换为对应类型,比如string)。

这种方式的优势是:只要修改outputParams的内容,返回类型会自动同步更新,无需手动修改类型定义,适合动态变化的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:50:14