【问题标题】:Determine the return type based upon the argument of a function in TypeScript根据 TypeScript 中函数的参数确定返回类型
【发布时间】:2020-11-13 06:04:48
【问题描述】:

在 TypeScript 中是否可以根据函数的参数确定函数的返回类型? 如果您想从例如获取属性的子集,这将很有帮助。数据库查询。

这是一个示例 (https://repl.it/repls/IrresponsibleUnsightlySequences#index.ts):

type QueryReturnType = {
  a: string;
  b: number;
  c: boolean;
};

const queryFunc = (): QueryReturnType => {
  return {
    a: 'b',
    b: 1,
    c: true,
  };
};

type Params = {
  [key: string]: keyof QueryReturnType;
};

const takeQuerySubset = (params: Params) => {
  const res: any = {};
  Object.keys(params).map((key) => {
    res[`${key}`] = queryFunc()[params[key]];
  });

  return res;
};

takeQuerySubset({ test1: 'a' }); // { test1: 'b' }

takeQuerySubset({ test2: 'b' }); // { test2: '1' }

takeQuerySubset({ test3: 'b', test4: 'c' }); // { test3: '1', test4: true }

这可行,但是 takeQuerySubset 的类型是:(params: Params) => any,而目标是获得基于参数的返回类型,即:

takeQuerySubset({ test1: 'a' }); // return type should be {test1: string}

takeQuerySubset({ test2: 'b' }); // return type should be {test2: number}

takeQuerySubset({ test3: 'b', test4: 'c' }) // return type should be {test3: number, test4: boolean}

这样使用 takeQuerySubset 的另一个函数就可以可靠地确定它将返回什么。

为了摆脱any,我尝试了泛型,但到目前为止没有运气。 另请注意,变量已重命名,即 a 现在称为 test1btest2,等等。

【问题讨论】:

    标签: typescript types typescript-typings


    【解决方案1】:

    这只能在一定程度上使用泛型 https://www.typescriptlang.org/docs/handbook/generics.html 。或者您使用交集和联合类型 https://www.typescriptlang.org/docs/handbook/advanced-types.html 。 您可以定义一个类型,例如数字或字符串(联合类型)。但是函数的调用者不知道函数的确切返回类型,因为它可能是数字或字符串。所以你可以和那里的类型保护人员核实一下。

    【讨论】:

    • 目标是事先知道返回值是什么,这样就不需要类型保护了。
    【解决方案2】:

    我想你只是想要这个:

    const takeQuerySubset = <T extends Record<string, any>>(params: T): T => {
      const res: any = {};
      Object.keys(params).map((key) => {
        res[`${key}`] = queryFunc()[params[key]];
      });
    
      return res;
    };
    

    【讨论】:

    • 看起来很有希望,但是,我无法编译它,因为您仍然可以将 any 作为索引类型。你能分享一个编译好的版本吗?例如在 repl.it 或 tsplayground 上?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    相关资源
    最近更新 更多