microsoft / microsoft/TypeScript

Dynamically named tuples

Ouverte
#44,939 8 commentaires 155 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Awaiting More Feedback Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.4k
Merge moyen
1 j 19 h
PR mergées (30 j)
117

Description

Suggestion

TypeScript's type system is extremely expansive and powerful, but one thing that I cannot seem to do is give tuples dynamic names. Eg:

type Test00 = [["name"]: number];

Or even:

type Test01 = [`name`: number];

Just like objects, we should be able to use bracket syntax to indicate that the expression inside should be used as the name.

We can then proceed to use other types to "calculate" the names.

🔍 Search Terms

  • tuple names
  • dynamic tuple names
  • changing tuple names
  • editing tuple names
  • calculated tuple names

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

I believe this one meets the last guideline because of goals 2 and 4.

⭐ Suggestion

Dynamically/calculated/inserted tuple names instead of static ones.

📃 Motivating Example

Consider the following example (ripped from a project of mine):

type Components = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26;

type Decrement<X extends number> = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25][X];

type CreateArray<T, L extends number> = L extends -1 ? [] : [T, ...CreateArray<T, Decrement<L>>];

type CanonicalAxisNames = ["", "x", "y", "z", "w", "v", "u", "t", "s", "r", "q", "p", "o", "n", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"];

type GetCanonicalAxisNames<C extends Components, R extends string[] = []> = C extends 0 | -1 ? R : GetCanonicalAxisNames<Decrement<C>, [CanonicalAxisNames[C], ...R]>;

type CreateVector<C extends Components> = {
    new (): VectorStruct<C>;
};

type VectorStruct<C extends Components> = {
    add(vector: VectorStruct<C>): VectorStruct<C>;
    add(...components: CreateArray<number, Decrement<C>>): VectorStruct<C>;
    add(scalar: number): VectorStruct<C>;
} & {
    [N in GetCanonicalAxisNames<C>[number]]: number;
}

declare function createVector<C extends Exclude<Components, -1 | 0>>(components: C): CreateVector<C>;

const Vector = createVector(3);

const v = new Vector();

v.add(0, 0, 0); // arguments are listed as components_0, components_1, and components_2

Instead of boring, bland names, I could use this new feature to give them more descriptive/detailed names.
Names are important because they describe the object in as few words as possible.
components_0 simply does not convey the same idea as x.

Suppose I create a type InsertTupleNames to create a tuple whose names are calculated, then I could use:

add(...components: InsertTupleNames<CreateArray<number, Decrement<C>>>): VectorStruct<C>;

Which means, the parameters are now named the correct names, and they make more sense to the end user.

Currently, I have to settle for a massive tuple containing all possible lists of parameter names, which is not ideal or maintainable.

💻 Use Cases

It would make more complex types/functions more readable/usable.

I think this example I have shown demonstrates that TypeScript's type system is extremely powerful, and so powerful that we can already create standalone types based on another one (aka CreateVector creates VectorStruct<...> and VectorStruct is a standalone type, functional, and solely created from CreateVector).

If we had this then we could make spread parameters and the outputted JavaScript easier to read with higher legibility.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

L’issue ne contient aucun fichier du dépôt, test ou point d’entrée par lequel commencer. Examinez d’abord les syntaxes proposées pour les noms de tuple ainsi que les exemples motivants InsertTupleNames et GetCanonicalAxisNames ; le travail sera considéré comme terminé lorsqu’il prendra en charge les noms de tuple calculés tout en préservant le comportement existant de TypeScript et de JavaScript.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
30/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.