type a = [1,2,3] type Invert<T extends any[] & {'0': any}> = ??? type b = Invert<a> // should yield [3,2,1] I am stucked to figure out the definition of Invert type of a tuple, also an Init and Last type, although they may be constructed of each otherswhat I have tried: position the type in a function param definition and infer the Rest part, this approach only got the Tail part with rest params
3 Réponses :
Cela ne fonctionne que lorsque vous connaissez la longueur du tableau:
export type Prepend<Tuple extends any[], Addend> = ((_: Addend, ..._1: Tuple) => any) extends ((..._: infer Result) => any) ? Result : never; export type Reverse<Tuple extends any[], Prefix extends any[] = []> = { 0: Prefix; 1: ((..._: Tuple) => any) extends ((_: infer First, ..._1: infer Next) => any) ? Reverse<Next, Prepend<Prefix, First>> : never; }[Tuple extends [any, ...any[]] ? 1 : 0]; type b = Reverse<[1, 2, 3]>; // type b = [3, 2, 1]
En fait, il existe une solution (trouvée ici à un problème du projet dactylographié):
type a = [1,2,3] type Invert<T extends [any, any, any]> = [T[2], T[1], T[0]]; type b = Invert<a> // should yield [3,2,1]
en fait, je veux obtenir une version générique
Si vous parlez d'une définition de type qui inverse un nombre quelconque d'entrées de tableau, cela n'est pas possible. Comme vous l'avez mentionné ci-dessus, cela nécessite un opérateur head and tail, qui à son tour nécessite un opérateur de repos en combinaison avec une récursivité pour les contraintes génériques. Les deux n'existent pas pour les génériques.
@Minami Mon dernier commentaire n'est pas vrai, il existe une version générique. Voir ma réponse mise à jour.
@ 1y1nq belle solution
à partir du code dactylographié 4.0 pour approcher un type inversé est beaucoup plus facile qu'avant, en disant
type Reverse<T extends any[], R extends any[] = []> = ReturnType<T extends [infer F, ...infer L] ? () => Reverse<L,[F,...R]> : () => R>
quelques explications:
Reverse
dans les typealias Reverse
entraînera une erreur de références circulaires.Reverse
type in function type ( ()=> Reverse
) désactivera l'erreur de références circulairesReturnType<() => Tup<L,[F,...R]>>
ne fera pas l'affaire, mais ReturnType<ConditionalType>
fera l'affaireTypeScript 4.1 a introduit les types conditionnels récursifs.
Ils permettent d'implémenter une fonction d'inversion de tuple comme ceci:
type Reverse<Tuple> = Tuple extends [infer Head, ...infer Rest] ? [...Reverse<Rest>, Head] : []; const test: Reverse<[1,2,3,4]> = [4,3,2,1];