2015-06-05 26 views
9

Zastanawiałem się, czy możliwe było wykorzystanie refleksji, a zwłaszcza refleksji klas dotyczącej dekoratora, właściwości, parametru czy metody?TypeScript 1.5, refleks i dekorator

Czy można użyć odbłyśnika, aby uzyskać informacje używane w dekoratorach?

Jeśli to możliwe, jak możemy to zrobić? Inaczej, dlaczego nie możemy tego zrobić?

EDIT:

Mam aplikacji, w których używam dekoratorów, aby wprowadzić dane z serviceRegistry, do dekoratora zwanego @Inject.

W tej aplikacji, wypełnić prosty rejestr usług przez strony, jak:

serviceRegistry.push(MyClass1) 
serviceRegistry.push(MyClass2) 
... 
serviceRegistry.push(MyClass100) 

Celem jest, aby być w stanie wypełnić ten rejestr usług z klas, które są ozdobione @ToInject adnotacji, w czasie wykonywania.

Pozwoli mi to uniknąć ręcznego wypełniania rejestru i automatyzować go w prosty sposób.

Dzięki za wcześniej

+0

[tutaj] (http://blogs.msdn.com/b/typescript/archive/2015 /04/30/announcing-typescript-1-5-beta.aspx) jest przykładem. Nie udało mi się go uruchomić z PhantomJS 2, który właśnie zgłosił błąd składni. –

+0

Jaki jest Twój ostateczny cel? Jeśli mógłbyś podać przykład, to pomogłoby ci odpowiedzieć na twoje pytanie. – zlumer

Odpowiedz

12

Można użyć refleksji importując pakiet reflect-metadata.

import 'reflect-metadata'; 

Użyj go z maszynopis 1,5 i flag kompilatora emitDecoratorMetadata wartość true. Nie zapomnij także o odwołaniu do reflect-metadata.d.ts.

Trzeba wdrożyć własne dekoratorów:

// declare property decorator 
function logType(target : any, key : string) { 
    var t = Reflect.getMetadata("design:type", target, key); 
    console.log(`${key} type: ${t.name}`); 
} 

class Demo{ 
    @logType // apply property decorator 
    public attr1 : string; 
} 

Będzie zalogować konsoli:

attr1 type: String 

Inny przykład:

// declare parameter decorator 
function logParamTypes(target : any, key : string) { 
    var types = Reflect.getMetadata("design:paramtypes", target, key); 
    var s = types.map(a => a.name).join(); 
    console.log(`${key} param types: ${s}`); 
} 

class Foo {} 
interface IFoo {} 

class Demo{ 
    @logParameters // apply parameter decorator 
    doSomething(
    param1 : string, 
    param2 : number, 
    param3 : Foo, 
    param4 : { test : string }, 
    param5 : IFoo, 
    param6 : Function, 
    param7 : (a : number) => void, 
) : number { 
     return 1 
    } 
} 

Będzie logowaniu w konsoli:

doSomething param types: String, Number, Foo, Object, Object, Function, Function 

Należy zauważyć, że interfejsy IFoo i literał obiektowy { test : string} są serializowane jako Object.Zasady serializacji są:

  • number szeregowane jako Number
  • string odcinkach jako String
  • boolean szeregowane jako Boolean
  • any serializowane jako Object
  • void serializes jak undefined
  • Array szeregowane jako Array
  • Jeżeli Tuple, szeregowane jako Array
  • Jeśli class szeregowane jako konstruktora klasy
  • Jeśli Enum szeregowane jako Number
  • Jeśli ma przynajmniej jeden podpis połączeń, serializowanym jak Function
  • W przeciwnym razie jest serializowany pod numerem Object (w tym interfejsy)

Interfejsy i obiekty mogą być serializowane w przyszłości poprzez serializację złożonych typów, ale ta funkcja nie jest obecnie dostępna.

Można również uzyskać typ zwracanej funkcji przy użyciu:

Reflect.getMetadata("design:returntype", target, key); 

Jeśli potrzebujesz więcej informacji na temat dekoratorów można przeczytać: Decorators & metadata reflection in TypeScript: From Novice to Expert

+0

Proszę wyjaśnić na "Nie zapomnij, w tym odniesienie do reflect-metadata.d.ts również."? – Learner

+2

Reflect-metadata zawiera pliki .d.ts w module npm. Kiedy napisałem tę odpowiedź, wymagane było użycie '/// ' do pliku dts. Dzisiaj, jeśli używasz TS> = 2.0, nie musisz tego robić. –

+0

Oto kolejny przykład dekoratorów użytkowania http://stackoverflow.com/questions/38085883/how-to-create-a-simple-typescript-metadata-annotation –

0

Właśnie wydany udoskonalona wersja kompilatora maszynopis że zapewnia pełne możliwości refleksji:

  • Ćwiczenia/interfaces metadanych w czasie wykonywania
  • klasy instancji z metadanych obiektów
  • Pobieranie metadanych z konstruktorów klasy

Można to sprawdzić here

+1

Czy mogę prosić, aby zadowolić opinię [Jak oferować osobowych typu otwarty biblioteki źródłowe?] (https://meta.stackexchange.com/q/229085) –

+0

Społeczność TypeScript prosi o możliwości refleksji od dłuższego czasu. To jest * * odpowiedź na pytanie. Żadna inna biblioteka/kompilator nie może obsłużyć tych wymagań. Spójrz na to. Ponadto powiedziałem: "Właśnie wydałem ...", więc jasne jest, że jest to projekt, który posiadam. – pcan

+1

Chodziło mi o to, że nie powinieneś kopiować dokładnie tej samej odpowiedzi bez szczegółów na każde pytanie dotyczące TypeScript tutaj bez dostosowywania swojej odpowiedzi i dołączania właściwych przykładów. –