【问题标题】:How to specify typescript conditional type based on a function return type in the arguments如何根据参数中的函数返回类型指定打字稿条件类型
【发布时间】:2019-09-02 11:36:00
【问题描述】:

我有这样的功能:

export const getValue = (
  options: Options = { someMapping, someFunction }
): string | MyType => {
  ...
  return someFunction({ ...someData });
};

现在,返回类型是 string 或 MyType。

这是因为 someFunction 可以返回字符串或 MyType。

有没有办法使用 TypeScript 条件类型根据 someFunction 实际返回的内容返回正确的类型?

[第一次发帖后的附加信息]:

下面是Options类型的定义:

export interface Options {
  someMapping: MappingType;
  someFunc: (data: MyType) => MyType | string;
}

someFunc 参数是一个需要 MyType 参数的函数。

这里是我根据情况传入的两个实际函数:

const myFunc = (data: MyType): string => {
  return data.someProperty;
};

const myFunc = (data: MyType): MyType => {
  return data;
};

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我认为你能做的最接近的是输入someFunction 并使用函数重载。 Options 让它有点复杂,但这样的事情应该可以工作:

    type MyFunc<T extends MyType | string> = () => T;
    
    interface Options<T extends MyType | string> {
      someMapping: WhateverTypeThisIs;
      someFunc: MyFunc<T>;
    }
    
    function getValue(options: Options<MyType>): MyType;
    function getValue(options: Options<string>): string;
    function getValue<T extends MyType | string>(options: Options<T>): T {
       return options.someFunc();
    }
    

    所以现在你应该得到这样的类型:

    const myTypeOptions: Options<MyType> = {
       someMapping: {},
       someFunc: () => ({ myParam: "MyValue" })
    };
    const myStringOptions: Options<string> = {
       someMapping: {},
       someFunc: () => "Hello"
    };
    const myTypeValue = getValue(myOptions); // myNumberValue is of type { myParam: string };
    const myStringValue = getValue(myStringOptions); // myStringValue is a string;
    

    这当然取决于所讨论的函数总是返回MyType或总是返回string这一事实。如果它根据函数的参数而变化,那么它将始终是MyType | string,因为 Typescript 无法确定这一点。由调用者来弄清楚它是什么。

    编辑:

    根据您提供的场景,这样的事情可能会有所帮助。您可以创建MyFunc 的类型。

    type MyTypeFunc = (myType: MyType) => MyType;
    type MyStringFunc = (myType: MyType) => string;
    
    interface MyOptions {
      someMapping: WatheverTypeThisIs;
    }
    
    interface MyTypeOptions extends MyOptions {
      someFunc: MyTypeFunc;
    }
    
    interface MyStringOptions extends MyOptions {
      someFunc: MyStringFunc;
    }
    
    function getValue(options: MyTypeOptions): MyType;
    function getValue(options: MyStringOptions): string;
    function getValue(options: MyTypeOptions | MyStringOptions): T {
       return options.someFunc();
    }
    

    现在,无论何时调用它,您都可以创建如下选项:

    const myTypeOptions: MyTypeOptions = {
      someMapping: {},
      someFunc: (myType) => myType
    }
    
    const myStringOptions: MyStringOptions = {
      someMapping: {},
      someFunc: (myType) => myType.someProperty
    }
    
    const myTypeValue = getValue(myTypeOptions); // myTypeValue will be of type MyType
    const myStringValue = getValue(myStringOptions); // myStringValue will be of type string
    

    【讨论】:

    • 嗨@DeeV,在我的情况下,MyFunc 只接受 MyType 的参数。我在我的帖子中添加了其他信息。我希望找到一些基于 myFunc 返回的实际类型的条件类型...
    • @techguy2000 我更新了我的答案。诀窍是定义两种类型的函数。
    • 如果没有必要,我不想定义更多的函数。我想弄清楚条件类型是如何工作的:stackoverflow.com/questions/55641731/…你有想法吗?
    • 我最终使用了函数重载。我想知道打字稿条件类型是否有用...
    【解决方案2】:

    playground 你可以让 typescript 推断返回类型。 @DeeV 提供的函数重载也可以。

    【讨论】:

      猜你喜欢
      • 2021-09-17
      • 2022-07-07
      • 1970-01-01
      • 2015-08-10
      • 2022-01-12
      • 2021-09-18
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多