microsoft / microsoft/TypeScript

Future-proof non-aliasing/always-expanding of mapped/intersection/union/etc. types

Abierto
#34,556 0 comentarios 28 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Needs Proposal Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

Search Terms

non-aliasing types

Suggestion

I would like an "officially blessed" way to tell TS if it should give me a type alias, or give me an "expanded" type. (See examples)

Now that this issue has been fixed,
https://github.com/microsoft/TypeScript/issues/32824

the technique I've been using to force TS to not alias a type will break when I migrate to TS 3.6/3.7

Use Cases

In some cases, seeing Mapped1<T>/Intersected1<T>/Unioned1<T> is better for a developer (see examples).

In other cases, seeing the full "expanded" type is better (see examples for Mapped2<T>/Intersected2<T>/Unioned2<T>)

Examples

type Identity<T> = T;

type Mapped1<T> = { [k in keyof T]: [T[k], "mapped"] };
type Mapped2<T> = Identity<{ [k in keyof T]: [T[k], "mapped"] }>;

declare function foo1(): Mapped1<{ x: string, y: number }>;
declare function foo2(): Mapped2<{ x: string, y: number }>;

/*
Aliased, bad
const m1: Mapped1<{
    x: string;
    y: number;
}>
*/
const m1 = foo1();
/*
Non-aliased, good
const m2: {
    x: [string, "mapped"];
    y: [number, "mapped"];
}
*/
const m2 = foo2();

//==============================================================

type Intersected1<T> = T & { hi: string };
type Intersected2<T> = Identity<T & { hi: string }>;

declare function bar1(): Intersected1<{ x: string, y: number }>;
declare function bar2(): Intersected2<{ x: string, y: number }>;

/*
const i1: Intersected1<{
    x: string;
    y: number;
}>
*/
const i1 = bar1();
/*
const i2: {
    x: string;
    y: number;
} & {
    hi: string;
}
*/
const i2 = bar2();

//==============================================================

type Unioned1<T> = T | { hi: string };
type Unioned2<T> = Identity<T | { hi: string }>;

declare function baz1(): Unioned1<{ x: string, y: number }>;
declare function baz2(): Unioned2<{ x: string, y: number }>;

/*
const u1: Unioned1<{
    x: string;
    y: number;
}>
*/
const u1 = baz1();
/*
const u2: {
    hi: string;
} | {
    x: string;
    y: number;
}
*/
const u2 = baz2();

Playground

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, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Related

https://github.com/microsoft/TypeScript/issues/32824#issuecomment-521127740

@weswigham brought up a different way to force TS to not alias a type.

I prefer my Identity<T> trick because it doesn't create a new "temporary" object type.

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

Comienza con los ejemplos de tipos mapped, intersection y union de este issue; después, revisa la discusión relacionada en el issue #32824 y el comentario enlazado. Se considera terminado cuando TypeScript tenga una forma oficialmente compatible de controlar si estos tipos permanecen como alias o se expanden, preservando los casos de uso mostrados.

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.