Typescript tilbakeringing med variable parametere udefinert
Jeg har problemer med å sende flere parametere gjennom en tilbakeringingsfunksjon. Av en eller annen grunn er ett av objektene udefinert.
Hvordan definerer jeg en tilbakeringingsfunksjon med flere parametere?
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
}
Svar #1
Problemet er hvordan du bruker call. Det første argumentet til call er this-parameteren som sendes til funksjonen, som siden du binder callbacken ikke vil være tilgjengelig i callbacken. Du kan sende null som det første argumentet og sende prosjektet som det andre argumentet og spre resten av argumentene som de andre argumentene:
callback.call(null, project, ...callbackArgs);
En bedre tilnærming ville være å ikke bruke call. Du kan bare kalle funksjonen som du normalt ville gjort:
callback(project, ...callbackArgs);
Du kan også bygge en helt typesikker versjon av koden din. I 3.2 er bind korrekt typet hvis du aktiverer strictBindCallApply (les PR). Dette betyr at vi kan bruke bind og få en korrekt typet funksjon. Kombiner dette med tupler i rest-parametere (PR) og vi kan få kompilatoren til å sjekke ting fullstendig for oss:
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()
