Hur säkerställer man att dekoratörens argument "target" utvidgar ett gränssnitt i TypeScript?


Jag lär mig TypeScript 2 och leker med dekoratorer och generiska T. Är det möjligt för en klassdekorator att säkerställa att dess mål utökar ett specifikt gränssnitt?

Så här (den här koden fungerar inte) :

interface IAction {}

function Action(options?:any) {
    return function(target:<T extends IAction>) {}
}

@Action()
export class CreateTodoAction implements IAction {}

Svar #1

interface Action {
  kind: string;
}

function action(options?: {}) {
    return function<T extends new(...args: {}[]) => Action>(target: T) {}
}

@action()
export class CreateTodoAction implements Action {
  kind = 'create';
}

Det är värt att notera att eftersom implements-klausulen är valfri i TypeScript, och eftersom dekoratören ändå tvingar den målklass som skapar instanser som uppfyller gränssnittet, finns det egentligen ingen riktig anledning att använda den i själva klassdefinitionen. Bara en fråga om stil, men det känns repetitivt.