programowanieFullstack deweloper

Jak działa dekorator typów (Decorator) w TypeScript? Do czego są używane, jak zrealizować własny dekorator i jakie pułapki napotykane są podczas pracy z nimi?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Dekoratory to specjalne adnotacje, które pozwalają na modyfikację zachowania klas, właściwości, metod lub parametrów poprzez dodatkowe metainformacje lub zastąpienie implementacji.

Zwykle używa się ich do wstrzykiwania zależności, logowania, walidacji, cache'owania lub deklarowania metadanych dla frameworków typu Angular.

Przykład prostego dekoratora metody:

function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Call: ${propertyKey}(${JSON.stringify(args)})`); return original.apply(this, args); }; } class Example { @Log doSomething(a: number, b: number) { return a + b; } }

Pułapki:

  • Dekoratory działają tylko wtedy, gdy włączono experimentalDecorators w tsconfig.
  • Nie są kompatybilne z niektórymi ustawieniami trybu surowego.
  • Dekoratory nie zawsze są wywoływane w oczekiwanej kolejności, ważne jest zrozumienie stosu wywołań.
  • Dekoratory na parametrach nie pozwalają na bezpośrednią zmianę ich wartości.

Pytanie z pułapką.

Pytanie: "Czy można typować parametry dekoratora w taki sposób, aby zagwarantować typ metody, do której jest stosowany?"

Odpowiedź: W większości przypadków typowanie jest niemożliwe na etapie zastosowania dekoratora z powodu dynamicznego charakteru metaprogramowania. Jednak za pomocą generics oraz dodatkowych sprawdzeń w czasie wykonywania można dodać walidację, ale kompilator TypeScript nie zapewni gwarancji na etapie deklaracji struktury.

Przykład:

function MyDecorator(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<number>) { /* ... */ } // Kompilator nie gwarantuje, że metoda zwraca number

Przykłady rzeczywistych błędów z powodu nieznajomości niuansów tematu.


Historia

W projekcie z dużą ilością dekoratorów w serwisach zapomniano o kolejności zastosowania: dekoratory właściwości zostały zastosowane przed wszystkimi parametrami, co spowodowało utratę metadanych Inject i niemożność rozwiązania zależności w czasie wykonywania.


Historia

Programiści postanowili zastosować dekoratory do zwykłych funkcji, a nie metod klas, i byli zaskoczeni błędami kompilacji oraz brakiem efektu w czasie wykonywania. W specyfikacji TypeScript dekoratory stosowane są tylko do klas i ich członków.


Historia

Po aktualizacji wersji TypeScript i ustawień eksperymentalnych cały mechanizm dekoratorów w niestandardowym kontenerze DI przestał działać: okazało się, że nowa wersja wymaga wyraźnego wsparcia Reflect-metadata, w przeciwnym razie cała metainformacja znika.