2017-05-05 4 views
0

Je veux un type pour les objets imbriqués, qui ont un type spécifique à leurs feuilles.Type pour les objets imbriqués avec des types de feuille spécifiques

Je pense que ce soit correct:

let a: Leaves<number> = { 
    "foo": 1, 
    "bar": { 
     "baz": 2 
    } 
}; 

et ce à faillir:

let a: Leaves<number> = { 
    "foo": 1, 
    "bar": { 
     "baz": 'something else' // Leaf of type string 
    } 
}; 

J'ai essayé

export type Leaves<T> = { 
    [P in keyof T]: T | Leaves<T>; 
} 

Cependant, avec cette définition les deux exemples donnent une erreur de compilation . Le premier dit Type '{ "foo": number; "bar": number; }' is not assignable to type 'number'.

Y at-il un moyen de résoudre ce problème?

Répondre

1

Si vous avez besoin d'un type pour un nœud avec les touches arbitraires et les valeurs que les feuilles ou autres noeuds, indexable type est le chemin à parcourir:

export type Leaves<T> = { 
    [n: string]: T | Leaves<T> 
} 

(BTW je préfère l'appeler Node<T>, pas Leaves<T>)

types cartographiées ne conviennent pas ici, car le type cartographié comme celui-ci

{ 
    [P in keyof T]: T | Leaves<T>; 
} 

ne peut avoir que les propriétés T a - c'est ce que dit [P in keyof T]:. Lorsque T est number, cela signifie que le type mappé peut avoir uniquement des propriétés de type number, et parce que number est primitif, cela signifie essentiellement qu'il est identique à number. C'est la raison pour le message d'erreur not assignable to number - tapuscrit essaie de trouver le type le plus descriptif à afficher dans le message d'erreur, et dans votre cas, il est juste number.

+0

Merci, c'était utile. Je suppose que j'étais un peu confus. – MaximeW