typescript - 如何在泛型函数类型中拥有可选参数类型?

标签 typescript generics

我有一个通用函数类型,如下所示:

type Test<TArg> = (arg: TArg) => void;

大多数时候,参数由符合这种类型的函数使用:

let x1: Test<number> = (n) => { console.log(n) };
let x2: Test<string> = (s) => { alert(s) };

虽然有时候,我有一个不接受任何参数的函数:

let y1: Test<undefined> = () => { };

我希望能够调用此函数而无需在调用点提供任何参数,如下所示:

y1();

但是无论我为 TArg 插入什么类型,我似乎都无法做到这一点。有没有在 Test 的定义中使参数可选的情况下执行此操作?

这是我尝试过的:

type Test<TArg> = (arg: TArg) => void;

let x: Test<number> = (n) => { console.log(n) };
let y1: Test<never> = () => { };
let y2: Test<any> = () => { };
let y3: Test<undefined> = () => { };
let y4: Test<null> = () => { };

x(1);
y1(); //Expected 1 arguments, but got 0.
y2(); //Expected 1 arguments, but got 0.
y3(); //Expected 1 arguments, but got 0.
y4(); //Expected 1 arguments, but got 0.

最佳答案

如果有一个执行包装器是可以接受的,我想出了一个解决方案来处理函数长度(0 或 1),并且对于参数来说是类型安全的:

type Test<T> = (arg?: T) => void;

class Wrapper<T, F extends Test<T>> {
    public execute: F;

    public static create<T1, F1 extends Test<T1>>(method: F1): Wrapper<T1, F1> {
        return new Wrapper(method);
    }

    constructor(method: F) {
        this.execute = method;
    }
}

const func1 = Wrapper.create((a: string) => console.log(a));
const func2 = Wrapper.create(() => { });

func1.execute('3');
func2.execute();

func1.execute(5); // 5 is not assignable to type "string"
func1.execute(); // expected 1 argument
func2.execute(5); // expected 0 arguments

请注意,如果您想将其扩展到超过 1 个参数,您可以添加额外的泛型类型,但您必须手动定义每个泛型类型并通过包装类传递它,但它会起作用。

EDIT 删除了原始的可选参数解决方案

关于typescript - 如何在泛型函数类型中拥有可选参数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48410510/

相关文章:

java - 以循环方式从 map /任何集合中获取值

Java 泛型 : wildcard and type parameter syntax when defining generic class

java - 使用泛型参数实例化泛型类时出错

css - 从 Angular Typescript 导入 css3/compass

reactjs - 在 Typescript 中使用 useContext 传递状态

javascript - Angular 2 应用程序转移到服务层后逻辑无法正常工作

java - 如何调用泛型类型的get方法?

java - 这个java程序有错误吗?

node.js - 如何使用 npm 命令编译 typescript ?

javascript - 如何让 TypeScript 执行尾递归优化?