
Hoy nos complace anunciar la disponibilidad de nuestro candidato de versión (RC) de TypeScript 3.3. Nuestra esperanza es recopilar comentarios y problemas iniciales para garantizar que nuestro lanzamiento final sea fácil de recoger y usar de inmediato.
Original en blogPara comenzar a usar el RC, puede obtenerlo a través de NuGet o usar npm con el siguiente comando:
npm install -g typescript@rc
También puede obtener soporte del editor por
TypeScript 3.3 debería ser una versión fácil de adoptar y no contiene cambios importantes. Exploremos las novedades en 3.3.
Comportamiento mejorado para llamar a tipos de unión
Cuando TypeScript tiene una unión tipo A | B
A | B
, le permite acceder a todas las propiedades comunes a A
y B
(es decir, la intersección de miembros).
interface A { aProp: string; commonProp: string; } interface B { bProp: number; commonProp: number } type Union = A | B; declare let x: Union; x.aProp;
Este comportamiento debe parecer intuitivo: solo puede obtener una propiedad de un tipo de unión si se sabe que está en cada tipo de unión.
¿Qué pasa, en lugar de acceder a las propiedades, estamos tratando con tipos de llamadas? Bueno, cuando cada tipo tiene exactamente una firma con parámetros idénticos, las cosas simplemente funcionan y puede llamar a estos tipos.
type CallableA = (x: boolean) => string; type CallableB = (x: boolean) => number; type CallableUnion = CallableA | CallableB; declare let f: CallableUnion; let x = f(true);
Sin embargo, esta restricción fue a veces, bueno, demasiado restrictiva.
type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number;
Dejando a un lado el ejemplo tonto y el mensaje de error deficiente, tanto FruitEater
como ColorConsumer
deberían poder tomar la cadena "orange"
y devolver un number
o una string
.
En TypeScript 3.3, esto ya no es un error.
type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number;
En TypeScript 3.3, los parámetros de estas firmas se cruzan para crear una nueva firma. En el ejemplo anterior, los parámetros fruit
y color
se cruzan entre sí con un nuevo parámetro de tipo Fruit & Color
. Fruit & Color
es realmente lo mismo que ("apple" | "orange") & ("red" | "orange")
que es equivalente a ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
. Cada una de esas intersecciones imposibles se evapora, y nos queda con "orange" & "orange"
que es simplemente "orange"
.
Sin embargo, todavía hay algunas restricciones. Este nuevo comportamiento solo se activa cuando, como máximo, un tipo en la unión tiene múltiples sobrecargas, y como máximo un tipo en la unión tiene una firma genérica. Eso significa métodos en el number[] | string[]
number[] | string[]
como map
(que es genérico) todavía no será invocable.
Por otro lado, los métodos como forEach
ahora serán invocables, pero bajo noImplicitAny
puede haber algunos problemas.
interface Dog { kind: "pupper" dogProp: any; } interface Cat { kind: "kittyface" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach(animal => {
Si bien continuaremos mejorando la experiencia aquí, esto es estrictamente más capaz en TypeScript 3.3, y agregar una anotación de tipo explícito funcionará.
interface Dog { kind: "pupper" dogProp: any; } interface Cat { kind: "kittyface" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach((animal: Dog | Cat) => { if (animal.kind === "pupper") { animal.dogProp;
--build --watch
incremental de archivos para proyectos compuestos en --build --watch
En TypeScript 3.0, presentamos una nueva característica para estructurar compilaciones llamada "proyectos compuestos". Parte del objetivo aquí era garantizar que los usuarios pudieran dividir los proyectos grandes en partes más pequeñas que se construyen rápidamente y preservan la estructura del proyecto, sin comprometer la experiencia existente de TypeScript. Gracias a los proyectos compuestos, TypeScript puede usar el modo --build
para recompilar solo el conjunto de proyectos y dependencias. Puede pensar en esto como la optimización de compilaciones entre proyectos.
Sin embargo, alrededor del año pasado, nuestro equipo también envió --watch
optimizadas en modo de --watch
través de una nueva API incremental de "constructor". En una línea similar, la idea es que este modo solo vuelve a verificar y vuelve a emitir archivos modificados o archivos cuyas dependencias pueden afectar la verificación de tipos. Puede pensar en esto como la optimización de las compilaciones dentro del proyecto.
Quizás, irónicamente, construir proyectos compuestos usando --build --watch
realidad no usó esta infraestructura. Una actualización en un proyecto en el modo --build --watch
forzaría una compilación completa de ese proyecto, en lugar de determinar qué archivos dentro de ese proyecto se vieron afectados.
En TypeScript 3.3, el --build
modo de --watch
aprovecha la observación incremental de archivos. Eso puede significar construcciones significativamente más rápidas en --build --watch
. En nuestras pruebas, esta funcionalidad ha dado como resultado una reducción del 50% al 75% en los tiempos de construcción de los tiempos originales de --build --watch
. Puede leer más sobre la solicitud de extracción original para el cambio para ver números específicos, pero creemos que la mayoría de los usuarios de proyectos compuestos verán ganancias significativas aquí.
Que sigue
Más allá de 3.3, puede estar atento a nuestra página de Hoja de ruta para cualquier trabajo futuro.
Pero en este momento esperamos escuchar su experiencia con el RC, ¡así que pruébelo ahora y díganos qué piensa!
- Daniel Rosenwasser y el equipo de TypeScript