gpt4 book ai didi

typescript - 更清洁的函数重载而不复制不变的部分

转载 作者:行者123 更新时间:2023-12-04 07:23:22 25 4
gpt4 key购买 nike

type Foo = {
(trx: Transaction | undefined, event: SomeEnum.OPT_1, params: { whatever: number }): Promise<void>;
(trx: Transaction | undefined, event: SomeEnum.OPT_2, params: { whatever: string }): Promise<void>;
};

export const foo: Foo = async (trx: Transaction | undefined, event: SomeEnum, params: object | undefined) => {};
我正在尝试函数重载,上面的代码有效,但在我的真实世界中,我将有 40 次重载,其中只有一些参数不同,所以我想知道,有没有办法改进代码,所以我不必一遍又一遍地复制所有不变的元素?在示例中,第一个参数 trx将始终相同,函数的返回类型也将始终相同。我尝试过这样的事情,但 typescript 显然不喜欢它:
type FooPartial<T1 extends SomeEnum, T2> = (trx: Transaction | undefined, event: T1, params: T2) => Promise<void>;

type Foo {
FooPartial<SomeEnum.OPT_1, { whatever: number }>
FooPartial<SomeEnum.OPT_2, { whatever: string }>
}

最佳答案

您需要进行动态重载。
为了做到这一点,你需要:

  • 计算循环中的每个重载


  • type Transaction = {
    tag: 'Transaction'
    }

    type Maps = {
    [SomeEnum.OPT_1]: string;
    [SomeEnum.OPT_2]: number
    }


    type Overloading = {
    [Ev in keyof Maps]: (trx: Transaction | undefined, event: Ev, params: Maps[Ev]) => Promise<void>
    }
  • 现在我们应该只得到 Overloading 的值类型

  • type Values<T> = T[keyof T]

    type Overloading = Values<{
    [Ev in keyof Maps]: (trx: Transaction | undefined, event: Ev, params: Maps[Ev]) => Promise<void>
    }>
  • 现在,当我们拥有所有允许函数的联合时,我们需要将这个联合转换为重载函数。为了做到这一点,你只需要使用一个交叉点 & .

  • // credits goes to https://stackoverflow.com/a/50375286
    type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
    k: infer I
    ) => void
    ? I
    : never;

    type Overloading =UnionToIntersection<Values<{
    [Ev in keyof Maps]: (trx: Transaction | undefined, event: Ev, params: Maps[Ev]) => Promise<void>
    }>>
    完整代码


    enum SomeEnum {
    OPT_1 = '1',
    OPT_2 = '2'
    }

    type Transaction = {
    tag: 'Transaction'
    }

    type Maps = {
    [SomeEnum.OPT_1]: string;
    [SomeEnum.OPT_2]: number
    }

    type Values<T> = T[keyof T]


    // credits goes to https://stackoverflow.com/a/50375286
    type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
    k: infer I
    ) => void
    ? I
    : never;

    type Overloading =UnionToIntersection<Values<{
    [Ev in keyof Maps]: (trx: Transaction | undefined, event: Ev, params: Maps[Ev]) => Promise<void>
    }>>

    export const foo: Overloading = async (trx: Transaction | undefined, event: SomeEnum, params: Values<Maps>) => { };

    foo({tag:'Transaction'}, SomeEnum.OPT_1, 'string') // ok
    Playground
    Here , 在我的博客中,您可以找到类似的解决方案

    关于typescript - 更清洁的函数重载而不复制不变的部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68365226/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com