2015-06-05 12 views
9

Mi chiedevo se fosse possibile utilizzare il riflesso e in particolare la riflessione di classe sul decoratore, sulla proprietà, sui parametri o sul metodo?TypeScript 1.5, reflection and decorator

È possibile utilizzare il riflettore per ottenere le informazioni utilizzate nei decoratori?

Se è possibile, come possiamo farlo? Altrimenti, perché non possiamo farlo?

EDIT:

Ho un'applicazione in cui uso decoratori, inserire dei dati, da un serviceRegistry, ad un decoratore chiamato @Inject.

In questa applicazione, riempio un semplice registro di servizio a mano, come:

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

L'obiettivo è quello di essere in grado di riempire questo registro di servizio con le classi che sono decorate con annotazione @ToInject, in fase di esecuzione.

Questo mi consentirà di evitare di riempire questo registro manualmente e di automatizzarlo semplicemente.

Grazie per anticipo

+0

[qui] (http://blogs.msdn.com/b/typescript/archive/2015 /04/30/announcing-typescript-1-5-beta.aspx) è un esempio. Non ho avuto modo di lavorare con PhantomJS 2 che ha appena segnalato un errore di sintassi. –

+0

Qual è il tuo obiettivo finale? Se potessi fornire un esempio, sarebbe utile rispondere alla tua domanda. – zlumer

risposta

12

È possibile utilizzare riflessione importando il pacchetto reflect-metadata.

import 'reflect-metadata'; 

utilizzarlo con dattiloscritto 1.5 e il compilatore di bandiera emitDecoratorMetadata impostato su true. Non dimenticare di includere anche un riferimento a reflect-metadata.d.ts.

è necessario implementare le proprie decoratori:

// 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; 
} 

Sarà il login console:

attr1 type: String 

Un altro esempio:

// 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 
    } 
} 

Sarà il login console:

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

Si noti che le interfacce IFoo e l'oggetto letterale { test : string} sono serializzate come Object.Le regole di serializzazione sono:

  • number serializzato come Number
  • string serializzato come String
  • boolean serializzato come Boolean
  • any serializzato come Object
  • void serializza come undefined
  • Array serializzato come Array
  • Se un Tuple, serializzato come Array
  • Se un class serializzato come il costruttore della classe
  • Se un Enum serializzato come Number
  • Se ha almeno una firma di chiamata, serializzato come Function
  • Altrimenti serializzato come Object (interfacce Compreso)

Le interfacce e gli oggetti letterali possono essere serializzati in futuro tramite la serializzazione di tipo complesso ma questa funzione non è disponibile al momento.

È anche possibile ottenere il tipo di ritorno di una funzione tramite:

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

Se avete bisogno di più informazioni su decoratori si può leggere: Decorators & metadata reflection in TypeScript: From Novice to Expert

+0

Potresti per favore approfondire "Non dimenticare di includere anche un riferimento a reflect-metadata.d.ts."? – Learner

+2

I metadati Reflect includono i file .d.ts nel modulo npm. Quando ho scritto questa risposta è stato necessario usare un '/// ' nel file dts. Oggi, se si utilizza TS> = 2.0, non è necessario farlo. –

+0

Ecco un altro esempio di utilizzo dei decoratori http://stackoverflow.com/questions/38085883/how-to-create-a-simple-typescript-metadata-annotation –

0

Ho appena rilasciato una versione migliorata del compilatore dattiloscritto che fornisce funzionalità di riflessione pieno:

  • Classi/interfacce di metadati a runtime
  • classi istanziare da metadati oggetti
  • recuperare i metadati da costruttori della classe

È possibile controllarlo fuori here

+1

Posso chiederti di leggere la recensione [Come offrire personale aperto- librerie di fonti?] (https://meta.stackexchange.com/q/229085) –

+0

La community TypeScript richiede capacità di riflessione da molto tempo. Questa è * la * risposta alla domanda. Nessun'altra versione di libreria/compilatore può gestire questi requisiti. Date un'occhiata a questo. Inoltre, ho detto "Ho appena rilasciato .." quindi è chiaro che è un progetto che possiedo. – pcan

+1

Intendevo di più che non dovresti copiare la stessa risposta esatta senza dettagli a tutte le domande su TypeScript senza personalizzare la risposta e includere esempi appropriati. –