microsoft / microsoft/TypeScript
Future-proof non-aliasing/always-expanding of mapped/intersection/union/etc. types
Nadie ha tomado este issue todavía.
- 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();
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
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- 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