2016-03-30 10 views
13

Supponiamo che ci sia un file di battitura per la libreria X che include alcune interfacce.C'è un modo per "estrarre" il tipo di proprietà dell'interfaccia TypeScript?

interface I1 { 
    x: any; 
} 

interface I2 { 
    y: { 
     a: I1, 
     b: I1, 
     c: I1 
    } 
    z: any 
} 

Per lavorare con questa libreria devo passare intorno ad un oggetto che è esattamente lo stesso tipo I2.y. Posso naturalmente creare un'interfaccia identica nei miei file di origine:

interface MyInterface { 
    a: I1, 
    b: I1, 
    c: I1 
} 

let myVar: MyInterface; 

ma poi ho ottenere l'onere di tenerlo al passo con quello dalla biblioteca, inoltre può essere molto grande e il risultato in molte duplicazione del codice .

Pertanto, esiste un modo per "estrarre" il tipo di questa proprietà specifica dell'interfaccia? Qualcosa di simile a let myVar: typeof I2.y (che non funziona e genera l'errore "Impossibile trovare il nome I2"). Grazie in anticipo.


Edit: dopo aver giocato un po 'in TS Playground ho notato che seguente codice ottiene esattamente quello che voglio:

declare var x: I2; 
let y: typeof x.y; 

Tuttavia essa richiede una variabile ridondante x da dichiarare. Sto cercando un modo per raggiungere questo obiettivo senza quella dichiarazione.

+1

* che non funziona * - come si manifesta? Qual è il vero messaggio di errore che vedi? –

+0

@BartekBanachewicz aggiornato –

risposta

23

non è stato Po ssible prima ma per fortuna è ora, dal TypeScript version 2.1. È stato rilasciato il 7 dicembre 2016 e introduce i tipi di accesso indicizzati chiamati anche tipi di ricerca.

La sintassi appare esattamente come l'accesso all'elemento ma scritta al posto dei tipi. Quindi nel tuo caso:

interface I1 { 
    x: any; 
} 

interface I2 { 
    y: { 
     a: I1, 
     b: I1, 
     c: I1 
    } 
    z: any 
} 

let myVar: I2['y']; // indexed access type 

Ora myVar ha tipo di I2.y.

Verificare in TypeScript Playground.

+0

Nel caso in cui 'y' è un array, c'è un modo per estrarre il tipo di elementi?per esempio. I2 {y: {..} []} –

+0

@JohnB sì, puoi farlo esattamente nello stesso modo, perché gli indici di array sono proprio come le proprietà dell'oggetto. Dai un'occhiata qui: http://www.typescriptlang.org/play/#src=let%20x%3A%20Array%3Cnumber%3E%20%3D%20%5B%5D%3B%0D%0Alet%20y% 3A% 20typeof% 20x% 5B0% 5D% 3B% 20% 2F% 2Fy% 20is% 20del% 20type% 20% 22number% 22% 0D% 0A% 0D% 0A% 2F% 2Fworks% 20also% 20with% 20tuples% 0D% 0Alet% 20x1% 3A% 20% 5Bstring% 2C% 20boolean% 2C% 20number% 5D% 3B% 0D% 0Alet% 20y1% 3A% 20typeof% 20x1% 5B1% 5D% 3B% 20% 2F% 2Fy1% 20is% 20del% 20type% 20boolean –

+0

@JohnB sì, puoi accedervi allo stesso modo, ad es. 'I2 ['y'] [0]' Vedi: http://www.typescriptlang.org/play/index.html#src=interface%20I1%20%7B%0D%0A%20%20%20%20x % 3A% 20any% 3B% 0D% 0A% 7D% 0D% 0A% 0D% 0Ainterface% 20I2% 20% 7B% 0D% 0A% 20% 20% 20% 20y% 3A% 20Array% 3CI1% 3E% 0D% 0A % 20% 20% 20% 20z% 3A% 20any% 0D% 0A% 7D% 0D% 0A% 0D% 0Alet% 20myVar% 3A% 20I2% 5B'y '% 5D% 5B0% 5D% 3B% 0D% 0A% 0D% 0Aconsole.log (myVar.x)% 3B% 0D% 0A –

0

Un'interfaccia è come la definizione di un oggetto. Quindi y è una proprietà del tuo oggetto I2, cioè di un certo tipo, in tal caso "anonimo".

Si potrebbe utilizzare un'altra interfaccia per definire y e poi usarlo come tipo di y come questo

interface ytype { 
    a: I1; 
    b: I1; 
    c: I1; 
} 

interface I2 { 
    y: ytype; 
    z: any; 
} 

Si può mettere la vostra interfaccia in un file e utilizzare l'estratto in modo da poter importare in altri file del vostro progetti

export interface ytype { 
    a: I1; 
    b: I1; 
    c: I1; 
} 



export interface I2 { 
     y: ytype; 
     z: any; 
    } 

è possibile importarlo in questo modo:

import {I1, I2, ytype} from 'your_file' 
+0

Va tutto bene, ma come ho già detto - le interfacce I1 e I2 provengono da una libreria esterna e sono definite nel file d.ts per quella libreria. Quindi avere questa interfaccia ytype sarebbe una duplicazione del codice e dovrebbe essere costantemente aggiornata. –

Problemi correlati