microsoft / microsoft/TypeScript

Dynamically named tuples

Abierto
#44,939 8 comentarios 155 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Awaiting More Feedback Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.4k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

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.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

El issue no contiene archivos del repositorio, pruebas ni puntos de entrada desde los que empezar. Revisa primero las sintaxis propuestas para nombres de tuplas y los ejemplos motivadores InsertTupleNames y GetCanonicalAxisNames; se considerará terminado cuando se admitan nombres de tuplas calculados, preservando el comportamiento existente de TypeScript y JavaScript.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
30/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.