typescript - Egenskapsdekorator kun for en bestemt egenskapstype


Jeg har en eienskapsdekoratør i TypeScript som bare kan brukes på eiendommer av typen Array. For å håndheve dette, kastes en TypeError under kjøring hvis eienskapstypen ikke er Array (ved å bruke reflect-metadata for å hente informasjon om eiendomstypen):

function ArrayLog(target: any, propertyKey: string) {
    if (Reflect.getMetadata("design:type", target, propertyKey) !== Array) {
        throw new TypeError();
    }

    // ...
}

Jeg vil imidlertid ikke betrakte dette som spesielt utviklervennlig. Hvordan kan jeg gjøre det slik at TypeScript-kompilatoren tillater bruk av en bestemt egenskapsdekoratør kun på egenskaper med en bestemt type?

Svar #1

Det er et lite triks for å oppnå dette:

function ArrayLog<K extends string, C extends { [ A in K ]: Array<any> }>(target: C, key: K) {
    /* ... */
}

Eller enda bedre (Fikk nettopp funnet på https://stackoverflow.com/a/47425850/274473):

function ArrayLog<K extends string, C extends Record<K, Array<any>>>(target: C, key: K) {
    /* ... */
}

Dessverre fungerer dette bare for offentlige egenskaper, ikke for private eller beskyttede egenskaper...

Svar #2

Feilen du får skyldes at returuttrykket mangler.

Prøv noe i retning av:

export function Decorator(fn:any) {
  return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<Array>) => {
    if (Reflect.getMetadata("design:type", target, propertyKey) !== Array) {
        throw new TypeError();
    } 
    return descriptor;
  };
}

Relaterte artikler