funktion - Videregivelse af klassemetode som parameter i Typescript
Jeg søger efter en mulighed for at videregive en klassemetode til en funktion, som derefter kan udføre den funktion på en instans af den klasse. Noget i stil med denne pseudokode: (bemærk, at dette er et abstrakt eksempel)
class Foo {
public somefunc() {
// do some
}
public anyfunc() {
// do any
}
}
function bar(obj: Foo ,func: "Foo.method") { // "that's what im looking for"
obj.func();
}
bar(new Foo(), Foo.somefunc); // do some
bar(new Foo(), Foo.anyfunc); // do any
Er der en mulighed for at gøre dette?
Jeg ved, jeg kunne lave noget lignende:
class Foo {
static somefunc(fooObj: Foo) {
// do some
}
static anyfunc(fooObj: Foo) {
// do any
}
}
interface func {
(fooObj: Foo);
}
function bar(obj: Foo, fn: func) {
fn(obj);
}
bar(new Foo(), Foo.somefunc); // do some
bar(new Foo(), Foo.anyfunc); // do any
men det involverer statiske funktioner, hvilket jeg ikke ønsker.
Svar #1
Dette kontrollerer ikke ved kompileringstidspunktet, at funktionen kom fra en Foo, men gør resten:
class Foo {
public somefunc() {
// do some
}
public anyfunc() {
// do any
}
}
function bar(obj: Foo ,func: () => void) {
func.call(obj);
}
bar(new Foo(), Foo.prototype.somefunc); // do some
bar(new Foo(), Foo.prototype.anyfunc); // do any
Svar #2
Typescript 2+ løsning
TL;DR: TypeScript Playground, Repo med en demo
Fordele:
- Kontrol under kompilering.
- Vil ikke lade dig miste
dennekontekst, når du videregiver en instansmetode. - Tab ikke ydeevne: du behøver ikke at erklære klassens metoder som instansmetoder (f.eks.
public somefunc =() => { return this.prop; }) - Læs mere. - Rør ikke ved en klasses prototype.
- Konsistent signaturmønster: at videregive en callback som det første argument og
thisArgsom det andet (f.eks. Array.prototype.map()).
Overvej følgende kode:
class Foo {
private result: number = 42;
public func(this: Foo): number {
return this.result;
}
}
function action(): void {
console.log("Hello world!");
}
function bar(callbackFn: (this: void) => any, thisArg?: undefined): any;
function bar<T>(callbackFn: (this: T) => any, thisArg: T): any;
function bar<T, TResult>(callbackFn: (this: T) => TResult, thisArg: T): TResult {
return callbackFn.call(thisArg);
}
const foo = new Foo();
bar(action); // success
bar(foo.func); // ERROR: forgot to pass `thisArg`
bar(foo.func, foo); // success
Ret din opmærksomhed mod signaturen af Foo#func:
public func(this: Foo): number
Det angiver, at denne funktion skal kaldes i en kontekst af klassens instans. Dette er den første del af løsningen, som ikke vil lade dig miste this-konteksten.
Den anden del er bar-funktionsoverbelastninger:
function bar(callbackFn: (this: void) => any, thisArg?: undefined): any;
function bar<T>(callbackFn: (this: T) => any, thisArg: T): any;
function bar<T, TResult>(callbackFn: (this: T) => TResult, thisArg: T): TResult
Dette ville lade dig videregive generiske funktioner såvel som instansmetoder.
Du kan lære mere om disse emner i TypeScript-håndbogen:
thisparametre i callbacks- Funktionsoverbelastninger
- Generika
