Compilaciones más rápidas de TypeScript con --isolatedDeclarations

Spanish audio is available in the player settings
Rate this content
Bookmark

La comprobación de tipos en un código TypeScript puede ser lenta, especialmente para monorepos que contienen muchos proyectos que necesitan utilizar el comprobador de tipos para generar archivos de declaración de tipos. En esta charla, presentamos -por primera vez- una nueva característica de TypeScript en la que estamos trabajando llamada "Declaraciones Aisladas" que permite generar archivos DTS sin utilizar el comprobador de tipos en absoluto. Esto abre la puerta a una generación más rápida de declaraciones en TypeScript, así como en herramientas externas escritas en otros lenguajes como ESBuild y swc. Verás cómo utilizar esta nueva opción y tal vez (solo tal vez) te convenzas de los beneficios de los tipos de retorno explícitos. Lo más importante, mostraremos cómo las Declaraciones Aisladas permiten compilar en paralelo para distribuir el trabajo en los núcleos de tu CPU y mejorar significativamente la velocidad de compilación de tus proyectos TypeScript.

24 min
21 Sep, 2023

Video Summary and Transcription

Esta charla analiza los problemas de rendimiento en las compilaciones de TypeScript e introduce una nueva característica llamada declaraciones aisladas. Al ejecutar el compilador en paralelo y utilizar módulos aislados, se pueden lograr mejoras significativas en el rendimiento. Las declaraciones aisladas mejoran la velocidad de compilación, la compatibilidad con otras herramientas y requieren que los desarrolladores escriban tipos en el código. Esta característica tiene el potencial de aumentar aún más el rendimiento y podría estar disponible en TypeScript pronto.

Available in English

1. Introduction to TypeScript Builds

Short description:

Hola a todos. Bienvenidos a mi charla, Acelerando las compilaciones de TypeScript. Voy a hablar sobre el rendimiento de las compilaciones, especialmente en monorepos. Estamos desarrollando una nueva función en colaboración con Bloomberg, Google y Microsoft. La motivación de esta función son las quejas sobre el rendimiento de las compilaciones en TypeScript. Intentamos ejecutar el compilador en paralelo, lo que resultó en mejoras significativas de rendimiento para un monorepo de 23 proyectos.

Mi nombre es Tiziano Cernico-Adragomir. Soy un ingeniero de software en Bloomberg en el equipo de infraestructura de TypeScript y JavaScript, y también soy colaborador del compilador de TypeScript.

Y hoy quiero hablar sobre el rendimiento de las compilaciones, especialmente el rendimiento de las compilaciones en monorepos. Y vamos a hablar sobre una nueva función de TypeScript que hemos estado desarrollando en colaboración con Bloomberg, Google y Microsoft. Pueden ver esta función en nuestro repositorio público de GitHub en nuestro fork de TypeScript. Pero también vamos a hablar de ella hoy.

Entonces, ¿cuál es la motivación de esta función? Bueno, si pasas cualquier cantidad de tiempo en Twitter, definitivamente encontrarás personas que se quejan del rendimiento de las compilaciones en TypeScript. Y estas quejas no son infundadas. Desafortunadamente, la comprobación de tipos puede ser lenta, especialmente si tienes mucho código en muchos proyectos en un monorepo. Entonces, la pregunta es, ¿qué podemos hacer al respecto? Bueno, podríamos optimizar el compilador, y el equipo de TypeScript definitivamente ha estado haciendo eso. Si revisas las notas de la versión de las últimas versiones, verás que cada versión trae nuevas optimizaciones al compilador. Y ese es un gran trabajo. También podríamos reescribir el compilador, y hay esfuerzos en marcha que están tratando de hacer eso. Estamos emocionados de ver a dónde llegan esos esfuerzos también. Pero probamos un enfoque diferente. Pensamos en ejecutar las cosas en paralelo, porque muchos dispositivos hoy en día tienen múltiples núcleos, las personas tienen muchos núcleos en sus escritorios y laptops. Y sería genial si pudiéramos aprovechar esos para hacer las cosas más rápidas para las personas cuando construyen sus proyectos. Así que ejecutemos el compilador en paralelo. Veamos qué mejoras de rendimiento podemos obtener. Lo que hicimos en Silent Bloomer, tomamos uno de nuestros propios monorepos. Era un monorepo de 23 proyectos. Tenía más de 100,000 líneas de código de TypeScript y un grafo de dependencias muy profundo, así que puedes pensar en algo como esto, muchos proyectos con muchas dependencias. Y tratamos de ver qué mejoras podríamos obtener al ejecutar el comprobador de tipos en paralelo para este monorepo. Tomamos una línea base inicial utilizando el soporte de proyecto compuesto integrado de TypeScript, y obtuvimos tiempos de compilación de alrededor de 60 segundos a 30, dependiendo del hardware. Ahora, TypeScript-B, que es el soporte de proyecto compuesto en TypeScript, en realidad es de un solo hilo. No intentará construir nada en paralelo, por lo que todos estos proyectos se verifican individualmente en orden de sus dependencias. Así que veamos qué podemos hacer si intentamos ejecutar el compilador en paralelo. Lo que hicimos fue ejecutar una instancia separada del compilador para cada proyecto.

2. Optimizando el Paralelismo y la Gestión de Dependencias

Short description:

Agrupamos los proyectos en trabajadores con cachés compartidas. Sin embargo, los proyectos no son independientes, por lo que tenemos que esperar a que las dependencias terminen de construirse. Esto limita el paralelismo, permitiendo que solo se construyan unos pocos proyectos simultáneamente.

Ahora, no hicimos esto de manera ingenua. Hubo algunas optimizaciones que sí realizamos. Por ejemplo, agrupamos todos los proyectos en varios trabajadores, y cada uno de estos trabajadores tenía una caché de archivos compartida y una caché de árbol de sintaxis de archivos fuente compartida, que son optimizaciones que TypeScript ya realiza para su soporte de proyecto compuesto de todos modos. Así que solo estábamos tratando de emular eso.

Ahora, el problema con el que nos encontramos de inmediato es que los proyectos no son independientes. Por lo tanto, no podemos simplemente ejecutar todo en paralelo. Necesitamos esperar a que las dependencias terminen de construirse. Por ejemplo, para el diagrama que mostré antes de las dependencias, obtendríamos una ejecución que se ve algo así. Y ya podemos ver que tenemos un gran límite en el paralelismo y solo hay dos proyectos que se ejecutan en paralelo al mismo tiempo. Por lo tanto, solo dos proyectos se verifican en paralelo. E incluso en nuestro monorepo de muestra con 23 proyectos, solo podríamos construir alrededor de cuatro en paralelo.

3. Aumentando el Paralelismo y los Módulos Aislados

Short description:

En una computadora portátil con 12 núcleos, solo utilizamos parte de la potencia de cálculo, dejando núcleos de CPU inactivos. Ejecutar cosas en paralelo resulta en una mejora del 10-20%, pero no es dramática. TypeScript realiza la verificación de tipos, la emisión de declaraciones y la emisión de JavaScript para cada proyecto. Desbloquear la fase de verificación de tipos de un proyecto requiere las declaraciones disponibles de sus dependencias. Dependemos de la emisión de declaraciones aunque no elimine la necesidad de verificación de tipos. El modo de módulos aislados de TypeScript permite la emisión de JavaScript sin la verificación de tipos de dependencia, convirtiéndolo en un proceso puramente sintáctico.

Ahora, ¿qué significa esto realmente? Por ejemplo, en una computadora portátil con 12 núcleos, que es lo que vemos aquí en esta imagen, solo utilizamos parte de esa potencia de cálculo. Podemos ver que incluso mientras se ejecuta la compilación, hay mucha potencia de CPU que aún no se está utilizando. Hay muchos núcleos de CPU que simplemente están inactivos. Así que definitivamente no es un buen comienzo para ejecutar cosas en paralelo.

Veamos a veces qué tipo de mejoras podríamos obtener si hiciéramos esto. Y la respuesta es que definitivamente obtendremos mejoras, pero simplemente no son tan grandes. Quiero decir, hay una mejora del 10-20% que obtenemos al ejecutar cosas en paralelo utilizando este enfoque, que nuevamente es mejor que lo que teníamos, pero no es algo que vaya a ser dramático.

Entonces, ¿cómo podemos aumentar el paralelismo disponible? ¿Cómo podemos ejecutar más cosas en paralelo? Bueno, para eso, primero que nada necesitamos entender exactamente lo que hace TypeScript, y lo que hace son tres cosas. Realiza la verificación de tipos, la emisión de declaraciones y la emisión de JavaScript. Estas cosas no son perfectamente independientes, es decir, la emisión de declaraciones depende del resultado de la verificación de tipos. Pero para cada uno de nuestros proyectos, TypeScript realizará estas tres cosas. Dentro de la compilación de cada uno de nuestros proyectos, todas estas tres cosas tienen que suceder.

Ahora, hay una idea clave aquí, y es que lo que se necesita para desbloquear la fase de verificación de tipos de un proyecto es que tenga disponibles todas las declaraciones de sus dependencias. Por lo tanto, la emisión de declaraciones es lo que realmente se necesita para las dependencias. No nos importa realmente si la dependencia ha terminado la verificación de tipos si podemos obtener sus declaraciones. Entonces, la cola de dependencias real se vería más o menos así, ¿verdad? Cada fase de verificación de tipos depende de la emisión de declaraciones de sus dependencias, no necesariamente de la verificación de tipos. Eso es un conocimiento interesante, pero mientras todavía tengamos esta dependencia entre la verificación de tipos y la emisión de declaraciones, el hecho de que dependamos de la emisión de declaraciones realmente no nos ayuda porque de todos modos necesitamos hacer la verificación de tipos. ¿Podríamos eliminar esta dependencia? Bueno, para eso, primero debemos analizar por qué la emisión de JavaScript es tan independiente de la verificación de tipos. ¿Cómo es eso? De hecho, incluso tenemos herramientas que hacen la emisión de JavaScript sin necesidad de un verificador de tipos. Lo hacen completamente independientemente de TypeScript. ¿Cómo se habilita esto? Bueno, hace unos años, TypeScript agregó un nuevo modo a TypeScript llamado módulos aislados. Entonces, ¿qué hace exactamente el modo de módulos aislados? Asegura que cada archivo pueda ser transpilado de TypeScript a JavaScript de forma individual. Básicamente, elimina cualquier dependencia de la verificación de tipos de la emisión de JavaScript. Esto significa que la emisión de JavaScript se convierte en un proceso puramente sintáctico. Las herramientas aún necesitan comprender la sintaxis de TypeScript. Cada vez que obtenemos una nueva sintaxis en TypeScript, todas las herramientas que hacen la emisión de JavaScript necesitan comprender esta nueva sintaxis. Pero la ventaja es que en realidad no necesitan comprender todas las reglas semánticas de TypeScript. Solo necesitan comprender la sintaxis lo suficiente como para poder eliminarla. Entonces, básicamente, cuando hacemos la emisión de JavaScript, comenzamos con un archivo de TypeScript, y lo que sucede dentro de un emisor de JavaScript es que se eliminan todas las anotaciones de tipo, ¿verdad? Y este es un proceso muy simple. No es difícil construir una transformación así. Al menos no es difícil en comparación con construir un verificador de tipos completo.

4. Eliminando la Dependencia y Declaraciones Aisladas

Short description:

Podemos eliminar la dependencia entre la emisión de declaraciones y la verificación de tipos al especificar todos los tipos en el archivo de TypeScript. Esto nos permitiría desbloquear las dependencias más rápido. TypeScript introduce la nueva característica llamada declaraciones aisladas, donde se agregan anotaciones de tipo a los valores que se incluyen en los archivos de declaración. El verificador de tipos no participa en la emisión de declaraciones para asegurar que siga siendo una transformación puramente sintáctica.

Entonces, ¿podríamos usar un enfoque similar para eliminar esta dependencia entre la emisión de declaraciones y la verificación de tipos? Para eso, tenemos que analizar un poco en qué consiste exactamente la emisión de declaraciones. En su mayor parte, también es un proceso de sustracción donde simplemente eliminamos cosas del archivo de TypeScript, excepto que ya no eliminamos los tipos. Estamos eliminando la implementación, por ejemplo, el cuerpo de la función, el cuerpo del constructor. Todo esto desaparece en los archivos de declaración.

Sin embargo, hay una excepción, en este caso, el tipo de retorno de esta función, porque si el desarrollador no especifica el tipo de retorno, la emisión de declaraciones debe acceder al verificador de tipos y averiguar cuál será el tipo de retorno de esta función. Y por eso se requiere la verificación de tipos para la emisión de declaraciones. Si todos escribieran todos los tipos en el archivo de TypeScript, en realidad no necesitaríamos el verificador de tipos para la emisión de declaraciones. Esta es una forma en la que podríamos eliminar la dependencia si especificamos todos los tipos, lo que nos permitiría desbloquear las dependencias más rápido.

Ya existen reglas de linting que podrían hacer cumplir esto, pero sería útil tener algo incorporado en la compilación real que garantice a otras herramientas qué anotaciones son necesarias. Por eso decidimos agregar una nueva bandera a TypeScript que llamamos declaraciones aisladas. Declaraciones aisladas es la nueva característica que estamos implementando. Veamos qué significa esta característica. Nuestra primera idea fue agregar anotaciones de tipo a todos los valores que se incluyen en los archivos de declaración. Esto se refiere principalmente a los valores exportados, aunque también hay algunas formas indirectas en las que los valores pueden incluirse en los archivos de declaración, incluso si no se exportan explícitamente.

Hicimos algunas excepciones. En algunos casos, los valores se pueden inferir fácilmente y tal vez podamos permitirlos sin tener anotaciones de tipo explícitas. Pero lo que es seguro es que el verificador de tipos en sí no puede participar en la emisión de declaraciones, porque queremos que la emisión de declaraciones sea puramente una transformación sintáctica donde simplemente eliminamos la implementación y no tenemos que acceder al verificador de tipos para obtener información de tipo del código fuente.

5. Anotación de Tipos e Inferencia

Short description:

No es necesario anotar todos los tipos a menos que optes por hacerlo. Si estás satisfecho con tus compilaciones de TypeScript, puedes mantener tu proyecto tal como está. Nuestra idea inicial era especificar anotaciones de tipo en todo, pero eso resultó ser difícil para proyectos grandes. Pasamos por tres fases de inferencia, pero encontramos problemas. Nuestro código requeriría anotaciones duplicadas para literales y objetos literales. Sin embargo, hicimos que la inferencia fuera más inteligente al inferir tipos para números y tipos literales, y al extraer información de la lista de parámetros para funciones.

Entonces, la siguiente pregunta lógica es, ¿tengo que anotar todos los tipos? Quiero señalar que no tienes que hacer nada a menos que optes por hacerlo. Si estás satisfecho con tus compilaciones de TypeScript, si estás satisfecho con la forma en que TypeScript fue y con tus tiempos de compilación, puedes mantener tu proyecto tal como está. Nadie te obliga a adoptar esto. Si tus dependencias adoptan esto, realmente no te importará porque solo estás consumiendo su archivo de declaración, por lo que no será algo en lo que todos tengan que optar.

Entonces, nuestra idea inicial, sin embargo, era que sí, necesitaríamos especificar anotaciones de tipo en todo. Resulta que esto hace que la conversión de proyectos grandes sea dolorosa y no es la mejor experiencia para los desarrolladores, especialmente al ver algunas de estas expresiones, podrías deducir fácilmente que sí, de hecho, el tipo de algo es un número. Pasamos por tres fases. Básicamente, la primera fue donde pensamos que no haríamos ninguna inferencia en este modo. La segunda fue donde pensamos que tal vez alguna inferencia trivial está bien. Y la última, que finalmente rechazamos, fue donde hacemos mucha más inferencia. Pero también nos encontramos con algunos problemas que veremos en unos momentos. Veamos cómo se vería nuestro código con cada una de estas versiones.

Entonces, sin inferencia. Lo que esto significaría es que tendrías que especificar tipos en absolutamente todo. Por ejemplo, estás asignando 20 a la variable margen. Es bastante obvio que el tipo debería ser número aquí, pero no permitimos ninguna anotación, por lo que tendrías que especificarlo. Tendrías que especificarlo para esta constante, básicamente duplicando el literal en ambos lugares, tanto en la posición del tipo como en el inicializador. Se vuelve aún peor para cosas como objetos literales, donde tienes que duplicar los nombres de las propiedades y los valores, y realmente se vuelve muy doloroso hacerlo. Para constantes que se inicializan con una función, bueno, tendrías que copiar la lista de parámetros nuevamente en la anotación de tipo, y también especificar el tipo de retorno. Y nuevamente, para campos, incluso si los estás inicializando con valores muy básicos, que debería ser obvio de qué tipo son, aún tendríamos que especificar el tipo explícitamente. Nuevamente, esto habría sido bastante doloroso y habría dificultado mucho que alguien realmente adopte esta característica. Así que decidimos hacer que nuestra declaración sea un poco más inteligente. Entonces, si vemos un literal de número, bueno, el tipo allí es obviamente número. Por lo que no necesitas especificarlo. Lo mismo para los tipos literales. Para los tipos de objeto, es un poco más complicado, pero no es imposible deducir el tipo a partir del inicializador. Así que decidimos que también podemos admitir esto. Para funciones que, para constantes que se inicializan con una función, bueno, no necesitas especificar toda la firma de la función como una anotación de tipo. Podemos extraer la mayor parte de la información que necesitamos de la lista de parámetros.

6. Inferencia Avanzada y Solución Rápida

Short description:

Deberás especificar el tipo de retorno. Para campos, puedes omitirlos si el inicializador es claro. El emisor de declaraciones de TypeScript es inteligente, pero queremos que sea simple y rápido. Podemos hacer más inferencia, pero no siempre será correcta. Las declaraciones tendrían que ser omitidas de manera optimista, lo que causaría problemas y complejidad. Añadir más inferencia podría degradar la experiencia del desarrollador. Para asegurar una adopción más fácil, hemos añadido una solución rápida.

Sin embargo, deberás especificar el tipo de retorno porque no queremos tener que entrar en el cuerpo de la función misma y buscar cualquier retorno e intentar sintetizar un tipo de retorno basado en eso. Y para los campos de función, y para los campos de clase, nuevamente, puedes simplemente omitirlos si el inicializador es lo suficientemente claro para que podamos inferir un tipo.

¿Qué pasa si queremos más, verdad? Estábamos muy emocionados por nuestro éxito inicial con esta forma trivial de inferencia, y decidimos, bueno, tal vez podamos hacer más. Tal vez podamos inferir más cosas. Y el problema es que el emisor de declaraciones de TypeScript es muy inteligente, y queremos que nuestros emisores sean simples y, con suerte, rápidos. Así que no queremos que el emisor de declaraciones, por ejemplo, tenga que buscar información en otros archivos. Así que pongamos un ejemplo. Digamos que tenemos una variable, y la estamos inicializando con el valor de otra variable. ¿Podríamos inferir trivialmente un tipo para orientation? ¿Qué tipo podríamos escribir en los archivos de declaración sin tener que involucrar al comprobador de tipos? Podríamos intentar usar typeOfHorizontal. Esto parece encajar muy bien. typeOf nos dará el tipo de la variable, y orientation debería tener el mismo tipo que lo que estamos asignando, ¿verdad? Bueno, a veces funciona. Por ejemplo, si horizontal está definido como una variable de tipo string, entonces sí, el tipo de horizontal será el mismo que el tipo de orientation porque ambos serán strings, y todo funcionaría muy bien. Sin embargo, si horizontal es una constante, entonces lo que realmente obtenemos para horizontal es el tipo literal horizontal. Entonces, ¿qué sucede cuando asignas esa variable a una variable mutable es que TypeScript realmente ampliará el tipo, por lo que orientation tendrá tipo string. Así que en este caso, el tipo de la variable horizontal será diferente que el tipo de la variable orientation porque tendremos básicamente string en un lado y horizontal en el otro lado. Así que no funciona en todos los casos. Entonces, ¿la respuesta es, podemos hacer más inferencia? La respuesta es sí, pero probablemente no siempre estaremos en lo correcto, por lo que las declaraciones tendrían que ser omitidas de manera optimista. Esto básicamente causa algunos problemas, sin embargo, porque lo que estamos diciendo aquí es que, bueno, un emisor de declaraciones podría producir declaraciones sin el comprobador de tipos, pero podrían estar equivocadas. Y luego TypeScript en sí podría regresar y generar un error al mirar toda la información en el sistema de tipos y decir, bueno, en este caso particular, si estás usando declaraciones aisladas y estás usando un emisor de declaraciones independiente, no podría haber sabido cuál era el tipo correcto allí. Así que esto es posible, pero crea un modelo mental muy complicado, lo que dificulta mucho la comprensión. Además, los errores serían mucho más difíciles de entender porque tendríamos que decirles a las personas por qué exactamente están teniendo un error en una cierta construcción. Y lo que obtuvimos fueron errores que sonaban algo como, este tipo que se infiere en las declaraciones aisladas es diferente de este otro tipo que se infiere normalmente por TypeScript. Y suena como si el compilador estuviera discutiendo consigo mismo. Las declaraciones aisladas son una cosa, el TSC normal dice otra cosa.

7. Mejorando la Experiencia del Desarrollador

Short description:

Agregar más inferencias que no siempre son correctas no es la mejor opción. Para asegurar una adopción más fácil, hemos añadido una solución rápida.

Y los desarrolladores involucrados básicamente no tienen participación en este proceso. Por lo tanto, todo esto podría resultar en degradar la experiencia del desarrollador en lugar de mejorarla, que fue la razón por la que queríamos más inferencia en primer lugar. Definitivamente, agregar más inferencias que no siempre son correctas no es la mejor opción.

Sin embargo, aún queríamos asegurarnos de que las personas tuvieran un tiempo más fácil adoptando esta característica. ¿Cómo podríamos asegurarlo? Bueno, decidimos agregar una solución rápida. La información ya está presente allí. Solo necesitamos insertar un tipo en nuestro código. Visual Studio Code ya tiene toda la información, el servicio de lenguaje que se ejecuta allí ya sabe cuáles son los tipos de todas las variables incluso si no están explícitos. Entonces, lo que podríamos hacer si hay una declaración aislada es simplemente usar una solución rápida para insertar el tipo sin tener que escribirlo nosotros mismos lo cual creo que definitivamente ayudará a todos los desarrolladores a adoptar esta característica.

8. Mejorando TypeScript con Declaraciones Aisladas

Short description:

Las declaraciones aisladas mejoran TypeScript de varias formas. Mejoran la velocidad y desbloquean más paralelismo al emitir las declaraciones de antemano. También mejoran la compatibilidad con otras herramientas y promueven la transparencia al requerir que los desarrolladores escriban tipos en el código.

Quiero enviar un agradecimiento especial a Hannah Jewell de Google que trabajó extensamente en esta característica y la mayor parte es gracias a ella.

Entonces, ¿cómo mejorarían las declaraciones aisladas a TypeScript? Bueno, esperamos mejorarla de varias formas. Con esta característica, en primer lugar, esperamos mejorar la velocidad, al pasar el verificador de tipos para sintetizar nuevos tipos probablemente mejorará la velocidad del límite de declaraciones por sí mismo. Esperamos desbloquear mucho más paralelismo. Si podemos emitir las declaraciones de antemano, los proyectos no necesitan esperar a que la fase de verificación de tipos de todas sus dependencias termine. Ya tienen las declaraciones y pueden realizar su propia verificación de tipos con eso. También esperamos mejorar la compatibilidad con otras herramientas. Como dije, ya existen herramientas que generan JavaScript a partir de TypeScript. Esperamos crear un ecosistema similar de herramientas que puedan emitir archivos de declaración sin el uso del verificador de tipos, pero que sean 100% compatibles con las declaraciones actuales de TypeScript. Y también esperamos mejorar la transparencia. A veces, los desarrolladores olvidan escribir tipos para sus valores exportados. Y a veces el verificador de tipos sintetiza algunas cosas que no son particularmente amigables para el desarrollador. Son tipos muy grandes o tipos sin ningún significado semántico, lo que resulta en una mala experiencia del desarrollador para los clientes de esas bibliotecas. Entonces, si las personas se ven obligadas a escribir estos tipos en el código, probablemente pensarán más en ellos y las declaraciones probablemente tendrán una mejor calidad solo por esto.

9. Mejorando el rendimiento con Declaraciones Aisladas

Short description:

Las declaraciones aisladas aumentan el paralelismo y mejoran el rendimiento de manera significativa. El futuro nos brinda la esperanza de obtener esta característica en TypeScript pronto, posiblemente en los próximos seis meses. Si bien no está claro si las declaraciones aisladas pueden ayudar en una configuración de proyecto único, existe el potencial de obtener un rendimiento aún más rápido con la posibilidad de un ecosistema de emisores de declaraciones de TypeScript. Agradecemos especialmente a todas las personas involucradas en el desarrollo de esta característica.

Pero volviendo a nuestro experimento de ejecutar la compilación de un monorepo en paralelo, vimos que sin declaraciones aisladas, había una cantidad limitada de paralelismo. Con las declaraciones aisladas, esperamos aumentar la cantidad de paralelismo disponible. Vimos que en la otra versión, esto era bastante limitado. En el mejor de los casos, dos proyectos podían verificar los tipos en paralelo en este ejemplo. Lo que queremos hacer es cargar todas las declaraciones de antemano, para desbloquear todos los proyectos lo más rápido posible. Queremos pasar de este diagrama a este diagrama. Con suerte, la diferencia entre estos dos es que esta vez no necesitaremos esperar a TypeScript porque la verificación de tipos se realizará mucho más rápido si podemos hacer todo esto en paralelo. Esa era la esperanza. Sin números reales, teóricamente esto podría funcionar. Pero en realidad no sabíamos qué tipo de mejoras de rendimiento estábamos viendo en proyectos reales.

Entonces, lo que hicimos fue convertir nuestro monorepo de muestra para usar declaraciones aisladas. Y tratamos de ver qué tipo de mejora de rendimiento obtendríamos al intentar compilar en paralelo con este nuevo enfoque de cargar todas las declaraciones de antemano. Así que, redoble de tambores, veamos los tiempos. Como puedes ver, incluso solo mirando los números, hay una gran mejora allí. Obtenemos tiempos de compilación de un solo dígito. Mirando un gráfico, tal vez se haga más claro que la mejora en el rendimiento es bastante dramática. Estamos hablando de una mejora de tres veces en el rendimiento. Cuando vimos estos números, realmente nos alegramos de que nuestra teoría funcionara y nuestras expectativas se cumplieran e incluso superaran en algunos aspectos.

Entonces, ¿qué nos depara el futuro? Bueno, esperamos obtener esta característica en TypeScript pronto. No sabemos exactamente cuándo, pero esperamos que suceda en los próximos seis meses. La otra pregunta que suelo recibir cuando hablo sobre esta característica es si esto puede ayudar en una configuración de proyecto único. Aún no estamos seguros de esto. Hemos realizado algunas experimentaciones, pero todavía hay algunas limitaciones que deben resolverse en el compilador de TypeScript primero. Veremos si podemos ayudar con eso también. ¿Puede esto volverse aún más rápido? Utilizamos la base del compilador de TypeScript para implementar nuestro propio emisor de declaraciones. Hay espacio para que otras herramientas sean mucho más rápidas, al igual que existe un ecosistema de emisores de JavaScript. Con suerte, habrá un ecosistema de emisores de declaraciones de TypeScript y eso hará que las cosas sean aún más rápidas.

Me gustaría agradecer a todas las personas involucradas de Google, Hannah Joo y Yann Kuehler, de Microsoft Daniel Rosenwasser, Jake Bailey y Ryan Kavanagh, y de Bloomberg, Rob Palmer, Thomas Chatwin y Ashley Claymore. También un agradecimiento especial al equipo de Flow, que implementó una característica muy similar hace un tiempo y que fue definitivamente una fuente de inspiración para nosotros. Muchas gracias por escuchar y estoy listo para responder cualquier pregunta en el chat. Gracias. Microsoft Mechanics www.microsoft.com www.microsoft.com www.facebook.com www.youtube.com

www.youtube.com

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
We don't think of React as shipping its own types. But React's types are a core part of the framework - overseen by the React team, and co-ordinated with React's major releases.In this live coding talk, we'll look at all the types you've been missing out on. How do you get the props type from a component? How do you know what ref a component takes? Should you use React.FC? And what's the deal with JSX.Element?You'll walk away with a bunch of exciting ideas to take to your React applications, and hopefully a new appreciation for the wonders of React and TypeScript working together.
Vue.js London 2023Vue.js London 2023
30 min
Stop Writing Your Routes
The more you keep working on an application, the more complicated its routing becomes, and the easier it is to make a mistake. ""Was the route named users or was it user?"", ""Did it have an id param or was it userId?"". If only TypeScript could tell you what are the possible names and params. If only you didn't have to write a single route anymore and let a plugin do it for you. In this talk we will go through what it took to bring automatically typed routes for Vue Router.
TypeScript Congress 2023TypeScript Congress 2023
31 min
Making Magic: Building a TypeScript-First Framework
I'll dive into the internals of Nuxt to describe how we've built a TypeScript-first framework that is deeply integrated with the user's IDE and type checking setup to offer end-to-end full-stack type safety, hints for layouts, middleware and more, typed runtime configuration options and even typed routing. Plus, I'll highlight what I'm most excited about doing in the days to come and how TypeScript makes that possible not just for us but for any library author.
React Advanced Conference 2021React Advanced Conference 2021
6 min
Full-stack & typesafe React (+Native) apps with tRPC.io
Top Content
Why are we devs so obsessed with decoupling things that are coupled nature? tRPC is a library that replaces the need for GraphQL or REST for internal APIs. When using it, you simply write backend functions whose input and output shapes are instantly inferred in your frontend without any code generation; making writing API schemas a thing of the past. It's lightweight, not tied to React, HTTP-cacheable, and can be incrementally adopted. In this talk, I'll give a glimpse of the DX you can get from tRPC and how (and why) to get started.
TypeScript Congress 2022TypeScript Congress 2022
10 min
How to properly handle URL slug changes in Next.js
Top Content
If you're using a headless CMS for storing content, you also work with URL slugs, the last parts of any URL. The problem is, content editors are able to freely change the slugs which can cause 404 errors, lost page ranks, broken links, and in the end confused visitors on your site. In this talk, I will present a solution for keeping a history of URL slugs in the CMS and explain how to implement a proper redirect mechanism (using TypeScript!) for dynamically generated pages on a Next.js website.

Add to the talk notes: https://github.com/ondrabus/kontent-boilerplate-next-js-ts-congress-2022 

Workshops on related topic

React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Workshop
TypeScript has a powerful type system with all sorts of fancy features for representing wild and wacky JavaScript states. But the syntax to do so isn't always straightforward, and the error messages aren't always precise in telling you what's wrong. Let's dive into how many of TypeScript's more powerful features really work, what kinds of real-world problems they solve, and how to wrestle the type system into submission so you can write truly excellent TypeScript code.
TypeScript Congress 2023TypeScript Congress 2023
131 min
Practice TypeScript Techniques Building React Server Components App
Workshop
In this hands-on workshop, Maurice will personally guide you through a series of exercises designed to empower you with a deep understanding of React Server Components and the power of TypeScript. Discover how to optimize your applications, improve performance, and unlock new possibilities.
 
During the workshop, you will:
- Maximize code maintainability and scalability with advanced TypeScript practices
- Unleash the performance benefits of React Server Components, surpassing traditional approaches
- Turbocharge your TypeScript with the power of Mapped Types
- Make your TypeScript types more secure with Opaque Types
- Explore the power of Template Literal Types when using Mapped Types
 
Maurice will virtually be by your side, offering comprehensive guidance and answering your questions as you navigate each exercise. By the end of the workshop, you'll have mastered React Server Components, armed with a newfound arsenal of TypeScript knowledge to supercharge your React applications.
 
Don't miss this opportunity to elevate your React expertise to new heights. Join our workshop and unlock the potential of React Server Components with TypeScript. Your apps will thank you.
TypeScript Congress 2022TypeScript Congress 2022
116 min
Advanced TypeScript types for fun and reliability
Workshop
If you're looking to get the most out of TypeScript, this workshop is for you! In this interactive workshop, we will explore the use of advanced types to improve the safety and predictability of your TypeScript code. You will learn when to use types like unknown or never. We will explore the use of type predicates, guards and exhaustive checking to make your TypeScript code more reliable both at compile and run-time. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Are you familiar with the basics of TypeScript and want to dive deeper? Then please join me with your laptop in this advanced and interactive workshop to learn all these topics and more.
You can find the slides, with links, here: http://theproblemsolver.nl/docs/ts-advanced-workshop.pdf
And the repository we will be using is here: https://github.com/mauricedb/ts-advanced
TestJS Summit 2023TestJS Summit 2023
78 min
Mastering Node.js Test Runner
Workshop
Node.js test runner is modern, fast, and doesn't require additional libraries, but understanding and using it well can be tricky. You will learn how to use Node.js test runner to its full potential. We'll show you how it compares to other tools, how to set it up, and how to run your tests effectively. During the workshop, we'll do exercises to help you get comfortable with filtering, using native assertions, running tests in parallel, using CLI, and more. We'll also talk about working with TypeScript, making custom reports, and code coverage.