web-dev-qa-db-fra.com

Existe-t-il un moyen "d'extraire" le type de propriété d'interface TypeScript?

Supposons qu'il existe un fichier de frappe pour la bibliothèque X qui inclut certaines interfaces.

interface I1 {
    x: any;
}

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

Afin de travailler avec cette bibliothèque, j'ai besoin de passer un objet qui est exactement du même type que I2.y. Je peux bien sûr créer une interface identique dans mes fichiers source:

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

let myVar: MyInterface;

mais alors je me charge de le tenir à jour avec celui de la bibliothèque, de plus, il peut être très volumineux et entraîner beaucoup de duplication de code. 

Par conséquent, y a-t-il un moyen "d'extraire" le type de cette propriété spécifique de l'interface? Quelque chose de semblable à let myVar: typeof I2.y (qui ne fonctionne pas et entraîne l'erreur "Impossible de trouver le nom I2"). Merci d'avance.


Edit : après avoir joué un peu à TS Playground, j’ai remarqué que le code suivant permettait exactement ce que je voulais:

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

Cependant, une variable redondante x doit être déclarée. Je cherche un moyen d'y parvenir sans cette déclaration.

31
Kuba Jagoda

Ce n'était pas possible auparavant, mais heureusement, c'est le cas maintenant, depuis TypeScript version 2.1 . Il a été publié le 7 décembre 2016 et introduit les types d'accès indexés, également appelés types lookup.

La syntaxe ressemble exactement à l'accès aux éléments mais est écrite à la place des types. Donc dans votre cas:

interface I1 {
    x: any;
}

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

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

Maintenant myVar a le type I2.y.

Découvrez-le dans TypeScript Playground .

54
Michał Miszczyszyn

Une interface est comme la définition d'un objet. Alors y est une propriété de votre objet I2, qui est d'un certain type, dans ce cas "anonymous".

Vous pouvez utiliser une autre interface pour définir y, puis l'utiliser comme type y, comme ceci 

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

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

Vous pouvez mettre votre interface dans un fichier et utiliser extract pour pouvoir l'importer dans d'autres fichiers de vos projets.

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



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

Vous pouvez l'importer de cette façon:

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