typescript - Reflect.getMetadata() returnerer undefined selv om metadata er satt


Jeg prøver å bruke annotasjoner i min TypeScript-applikasjon. Men jeg må gjøre noe galt, siden Reflect.getMetadata() alltid returnerer undefined, selv om jeg kan se i debuggeren at metadataene ser ut til å være satt riktig.

my-class.ts med en annotert egenskap:

import { jsonIgnore } from './json-ignor';

export class MyClass {
    public prop1: string;
    @jsonIgnore() public prop2: string;
}

json-ignore.ts med dekorasjons- og annotasjonsfunksjonen:

const JSON_IGNORE = 'jsonIgnore';

export function jsonIgnore(): any {
    return Reflect.metadata(JSON_IGNORE, true);
}

export function jsonIgnoreReplacer(key: string, value: any): any {
    const meta = Reflect.getMetadata(metadataKey, object, propertyKey);
    // do something with the metadata...
}

Nå er meta alltid undefined. Men når jeg sjekker MyClass-instansen i feilsøkeren, ser jeg at den har metadataen satt i prototypen sin:

  • minKlasse: MinKlasse

    • prop1: 'foo'
    • prop2: 'bar'
    • [[Prototype]]: Objekt

      • __metadata__:

        • prop2:

          • jsonIgnorer: sann
          • prop2:
          • jsonIgnorer: sann

          • __metadata__:
          • prop2:
          • jsonIgnore: true

Jeg kan også få tilgang til __metadata__ og dets oppføringer enkelt (Object.getPrototypeOf(myClass).__metadata__.prop2.jsonIgnore), men det er definitivt en løsning på hackernivå når det finnes et API for det, og vil mest sannsynlig ikke fungere i forskjellige nettlesere?

Så hvis noen kunne påpeke hva jeg gjør feil... ville det vært veldig mye verdsatt!

Mer info: tsconfig.json:

"compilerOptions": {
    ...
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
}

Svar #1

Det ser ut som om du har definert metadatakey-en din som en streng. Følger man instruksjonene i TypeScript-dokumentasjonen her, må du definere nøkkelen som et Symbol. Jeg har også lagt merke til at Symbolet faktisk må være den samme instansen i dekoratøren og funksjonen som bruker metadataene. Prøv dette:

    const jsonIgnoreMetadataKey = Symbol("jsonIgnore");
    export function jsonIgnore(): any {
        return Reflect.metadata(jsonIgnoreMetadataKey , true);
    }

    export function jsonIgnoreReplacer(key: string, value: any): any {
        const meta = Reflect.getMetadata(jsonIgnoreMetadataKey , object, propertyKey);
        // do something with the metadata...
     }

Relaterte artikler