带有可变参数的Typescript回调未定义

时间:2018-12-03 09:33:43

标签: typescript callback

我无法通过回调函数传递多个参数。 由于某种原因,是未定义的对象之一。

如何定义具有多个参数的回调函数?

  public save() {
    let oldStartDate = "2019-01-01";

    let newProject = new Project();
    newProject.oldStartDate = "2018-01-01";

    this.doSomeWork(newProject, this.workFinished_Callback.bind(this), oldStartDate);
  }

  public doSomeWork(project:Project, callback: (updatedProject: Project, ...param: any[]) => any = null, ...callbackArgs: any[]) {
    //Work work..
    console.log(project); //This exists..

    callback.call(project, ...callbackArgs);
  }

  public workFinished_Callback(project:Project, oldStartDate: string) {
    console.log(project); //This is undefined..
    console.log(oldStartDate); //Shows 2018-01-01
  }

1 个答案:

答案 0 :(得分:0)

问题在于您如何使用call。要调用的第一个参数是传递给函数的this参数,由于绑定了回调,因此在回调中将无法访问该参数。您可以将null作为第一个参数传递,并将项目作为第二个参数传递,并将其余的参数作为其他参数传播:

callback.call(null, project, ...callbackArgs);

更好的方法是不使用通话。您可以像平常一样调用该函数:

callback(project, ...callbackArgs);

您还可以构建代码的完全类型安全版本。在3.2中,如果启用bind(读入PR),则正确键入strictBindCallApply。这意味着我们可以使用bind并获得正确键入的函数。将其与其余参数(PR)中的元组配对,我们可以使编译器为我们进行全面检查:

class Project { oldStartDate!: string }
type DoSomeworkCallbackArgs<T extends (updatedProject: Project, ...param: any[]) => any> =
    T extends (updatedProject: Project, ...param: infer A) => any ? A : []
class DD {
    public save() {
        let oldStartDate = "2019-01-01";

        let newProject = new Project();
        newProject.oldStartDate = "2018-01-01";

        this.doSomeWork(newProject, this.workFinished_Callback.bind(this), oldStartDate);
        this.doSomeWork(newProject, this.workFinished_Callback.bind(this), 0); //error
    }

    public doSomeWork<T extends null | ((updatedProject: Project, ...param: any[]) => any)>(project: Project, callback: T = null, ...callbackArgs: DoSomeworkCallbackArgs<T>) {
        //Work work..
        console.log(project); //This exists..
        if (callback) callback(project, ...callbackArgs);
    }

    public workFinished_Callback(project: Project, oldStartDate: string) {
        console.log(project); // ok now
        console.log(oldStartDate); //Shows 2018-01-01

    }
}


new DD().save()