【问题标题】:Create a function type template in Typescript在 Typescript 中创建函数类型模板
【发布时间】:2020-05-14 08:48:39
【问题描述】:

我有一个类似以下的函数,但不那么简单:

function foo(arg1?: string | number | boolean, arg2?: number | boolean, arg3?: boolean) {
  // omitted
}

这个函数可以以多种不同的方式运行,例如:

foo();
foo(1, true);
foo("", false);
foo(4);
foo(true);
// ..etc

为了使上下文线索/类型定义可读,最好的方法是使用重载:

function foo();
function foo(name: string);
function foo(age: number);
function foo(nice: boolean);
function foo(name: string, age: number);
function foo(name: string, nice: boolean);
function foo(age: number, nice: boolean);
function foo(name: string; age: number, nice: boolean);
function foo(arg1?: string | number | boolean, arg2?: number | boolean, arg3?: boolean) {
  // omitted
}

// now it'll figure out which overload I'm on, and give easier to read insights

问题是我不只是有 foo。我有 foo、bar、qux、baz 和其他 30 个。写这一切将是一堵可怕的文字墙。所以我尝试为所有人制作一种类型,如果不是泛型,它会起作用:

// Without generics, this problem would be solved

export const bar = (function(...args: ArgOutline) {
  // omitted
}) as typeof foo

export const qux = (function(...args: ArgOutline) {
  // omitted
}) as typeof foo

export const baz = (function(...args: ArgOutline) {
  // omitted
}) as typeof foo

/// and so on...

我真正想要的是一个大纲函数,它采用泛型并且可以产生具有可读见解的东西,但是以下代码不起作用:

function Outline();
function Outline(name: string);
function Outline<PROPS>(props: PROPS);
function Outline(name: string props: PROPS);
function Outline<PROPS>(arg1?: string | PROPS, arg2?: PROPS) {
  // omitted
}


// This doesn't work
export const baz = (function(...args: ArgOutline) {
  // omitted
}) as typeof Outline<{a: number}> 

我已经阅读了为什么你不能这样做 (https://github.com/microsoft/TypeScript/issues/204),但似乎仍然有办法,只是不是这样。

我怎样才能创建一个泛型类型,它会产生(+N overloads) 而不是() =&gt; ReallyTerriblyLongName | (name: string) =&gt; ReallyTerriblyLongName | (name: string, props: AlsoATerriblyLongName) =&gt; ReallyTerriblyLongName | ...etc 的见解?

【问题讨论】:

    标签: typescript typeof


    【解决方案1】:

    尝试接口(我假设您的返回类型为 void):

    interface Outline {
        (): void;
        (name: string): void;
        <PROPS>(props: PROPS): void;
        <PROPS>(name: string, props: PROPS): void;
    }
    
    export const bar = function(...args: any[]) { } as Outline;
    

    您还可以将泛型参数移动到接口本身:

    interface Outline<PROPS> {
        (): void;
        (name: string): void;
        (props: PROPS): void;
        (name: string, props: PROPS): void;
    }
    
    export const bar = function(...args: any[]) { } as Outline<{ a: number }>;
    

    【讨论】:

    • 我醒来时想到了这个。很高兴看到这是最好的方法。
    【解决方案2】:

    真的是为​​了这个从床上爬起来的。

    function Outline<PROPS>() {
    
      function out();
      function out(name: string);
      function out(props: PROPS);
      function out(name: string props: PROPS);
      function out(arg1?: string | PROPS, arg2?: PROPS) {
        // omitted
      }
    
      return out;
    }
    
    // Create the outline, then get its type
    const bazOutline = Outline<{a: number}>();
    export const baz = (function(...args: ArgOutline) {
      // omitted
    }) as typeof bazOutline
    
    

    创建一个返回所需类型函数的函数。然后从中获取 typeof ......仍然需要在野外进行测试,但我现在得到了正确的类型定义。也许出口会中断。

    【讨论】:

      猜你喜欢
      • 2016-05-28
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 2010-11-01
      • 2014-06-03
      • 2019-08-13
      • 2017-11-02
      相关资源
      最近更新 更多