TypeScript 3.0

TypeScript 3.0! Sí, salió, y realmente tiene muchas innovaciones. Debajo del corte, encontrará una descripción detallada de todas las últimas innovaciones, incluido el modo de compilación, un nuevo tipo desconocido, cambios significativos en la API, mejoras de rendimiento y mucho más. Únete ahora!



¡TypeScript 3.0 lanzado! Un nuevo hito ha comenzado en el camino hacia el desarrollo de TypeScript, un asistente para todos los usuarios de JavaScript.

Si no está familiarizado con TypeScript, ¡no es demasiado tarde para aprenderlo ahora! TypeScript es una extensión de JavaScript diseñada para su uso en la versión moderna de este lenguaje de tipos estáticos. El compilador TypeScript lee el código TypeScript que contiene, en particular, declaraciones de tipo y anotaciones de tipo, y produce un código JavaScript limpio y fácil de leer en el que estas construcciones se transforman y eliminan. El código resultante se ejecuta en cualquier entorno de tiempo de ejecución que cumpla con el estándar ECMAScript, por ejemplo, en su navegador favorito o en la plataforma del servidor Node.js.

El uso de dicho entorno significa que el código se analizará en busca de errores o errores tipográficos antes de que los usuarios lo inicien, pero sus ventajas no se limitan a esto. Con toda esta información y resultados de análisis, TimeScript mejora la usabilidad al proporcionar herramientas de navegación y finalización de código automáticas como Buscar todas las referencias, Ir a definición y Cambiar nombre en su editor favorito. .

Para comenzar con el idioma y obtener más información, siga el enlace . Si desea probar TypeScript 3.0 ahora mismo, puede descargarlo de NuGet o npm escribiendo

npm install -g typescript 

Además, el soporte está disponible en los siguientes editores:


Otros editores se actualizan de acuerdo con su propia programación, pero pronto todos tendrán un excelente soporte de TypeScript.

Descripción general de la versión 3.0


Después del lanzamiento de TypeScript 2.0, brindamos una breve descripción de la contribución de las versiones anteriores a su estado actual. Entre los lanzamientos de TypeScript 1.0 y 2.0, el lenguaje incluye tipos de unión, protectores de tipos, soporte para el estándar ECMAScript moderno, alias de tipo, soporte JSX, this tipo literal y polimórfico. Si incluye tipos TypeScript 2.0 que no son nulos, análisis del flujo de control, soporte para uniones etiquetadas, este tipo y un modelo simplificado para recibir archivos .d.ts , podemos decir que este período determinó completamente los conceptos básicos. Trabajo tipográfico.

Entonces, ¿qué se ha hecho desde entonces? ¿Qué nos llevó a TypeScript 3.0, además de las nuevas características del estándar ECMAScript, como las funciones async / en await , los generadores y el operador rest / spread?

TypeScript 2.1 se convirtió en la versión fundamental, que introdujo un modelo de metaprogramación estática en JavaScript. Solicitud de clave ( keyof ), acceso al índice ( T[K] ) y tipos de objetos mapeados ( { [K in keyof T]: } T[K]} ): esta es una lista de herramientas que se utilizaron para modelar de manera más efectiva las bibliotecas React, Ember, Lodash y otros.

Las versiones de TypeScript 2.2 y 2.3 introdujeron soporte para plantillas de clase mixin, el tipo de object (que representa un objeto que no es primitivo) y valores predeterminados para tipos genéricos. Estas características se han utilizado en varios proyectos, como Angular Material y Polymer. Además, TypeScript 2.3 introdujo la capacidad de ajustar this tipos, permitiendo que el lenguaje funcione bien con bibliotecas como Vue, y se checkJs indicador checkJs para permitir que los tipos se verifiquen en archivos JavaScript.

TypeScript 2.4 y 2.6 continúan la historia de aumentar la severidad de la verificación de tipos de funciones, asociada con algunas de las revisiones más antiguas de nuestro sistema de tipos. Se --strictFunctionTypes el --strictFunctionTypes , forzando la contravarianza de los parámetros. En la versión 2.7, la tendencia hacia el rigor ha persistido y se ha expresado en la validación en clases que usan el indicador --strictPropertyInitialization .

TypeScript 2.8 introduce tipos condicionales, una poderosa herramienta para expresar estáticamente decisiones basadas en tipos, y la versión 2.9 generaliza la clave del operador y simplifica la importación de tipos.

¡Y eso nos lleva a TypeScript 3.0! A pesar del nuevo número entero en el número, poco ha cambiado en la versión 3.0 (lo que implica una actualización muy fácil). Presenta una nueva forma flexible y escalable de estructurar proyectos, un nuevo y poderoso soporte para trabajar con listas de parámetros, nuevos tipos para proporcionar verificaciones explícitas, soporte mejorado de JSX, diagnóstico de errores significativamente más fácil de usar y mucho más.

Que hay de nuevo


  • Enlaces de proyectos
    • --build Modo de --build
    • Gestión de estructura de salida
    • Planes futuros
  • Recuperando y distribuyendo listas de parámetros usando tuplas
  • Nuevas características de tipo Tuple
  • Tipo unknown
  • Diagnóstico de errores y entorno de usuario mejorados
    • Rangos de error asociados
    • Diagnóstico mejorado y manejo de errores
  • Soporte para la propiedad defaultProps en JSX
  • Directivas /// <reference lib="..." />
  • Mejorando la velocidad del editor
    • Refactorización de declaraciones de importación con nombre
    • Fin de etiqueta final y marco de contorno
    • Soluciones rápidas para código inalcanzable y etiquetas no utilizadas
  • Cambios críticos
    • unknown es un nombre de tipo reservado
    • Cambios críticos de API

Enlaces de proyectos


Muy a menudo, para construir una biblioteca o aplicación, debe seguir varios pasos. Suponga que su base de código contiene los directorios src y test . Suponga que tiene una carpeta de client donde se almacena el código de la parte del cliente de la aplicación, y una carpeta de servidor que contiene el código de parte del servidor en la plataforma Node.js, y cada uno de ellos toma parte del código de la carpeta shared . Quizás esté utilizando el llamado "repositorio único" y tenga muchos proyectos que dependen mucho entre sí.

Una de las características más importantes en las que trabajamos al lanzar TypeScript 3.0 se denominó "enlaces de proyecto" y está diseñada para simplificar el trabajo con dichos scripts.

Gracias a los enlaces de proyectos, algunos proyectos de TypeScript pueden depender de otros. En particular, los archivos tsconfig.json pueden hacer referencia a otros archivos tsconfig.json . La definición de estas dependencias facilita la división del código en proyectos más pequeños, porque el compilador TypeScript (y sus herramientas) tienen la oportunidad de comprender el orden de ensamblaje y la estructura de la salida. Esto significa que el ensamblaje es más rápido y se realiza de forma incremental (en etapas), se admite la navegación transparente, la edición y la refactorización para varios proyectos. Dado que TypeScript 3.0 sienta las bases para el proyecto y proporciona una API, cualquier herramienta de compilación debería poder proporcionar esto.

¿Cómo se ve?


Aquí hay un archivo tsconfig.json que contiene enlaces a proyectos como un ejemplo simple.

 // ./src/bar/tsconfig.json { "compilerOptions": { // Needed for project references. "composite": true, "declaration": true, // Other options... "outDir": "../../lib/bar", "strict": true, "module": "esnext", "moduleResolution": "node", }, "references": [ { "path": "../foo" } ] } 

Tiene dos nuevos campos: composite y references .

El campo de references simplemente apunta a otros archivos tsconfig.json (o las carpetas en las que están contenidos). Cada enlace aquí es simplemente un objeto con un campo de path ("ruta") y le dice al compilador de TypeScript que para construir este proyecto, primero debe construir otro proyecto al que se refiere.

Aparentemente, el campo composite tiene la misma importancia. El campo composite garantiza que ciertos parámetros estén habilitados para permitir que cualquier proyecto que dependa de esto lo haga referencia e lo incluya en compilaciones incrementales. La capacidad de construir de forma inteligente e incremental es importante, ya que una de las principales razones por las que puede abandonar un proyecto es la velocidad de construcción.

Por ejemplo, si el proyecto front-end depende del proyecto shared y del núcleo, entonces nuestras API relacionadas con los enlaces del proyecto ayudarán a identificar cambios en el núcleo, pero solo se recopilarán de nuevo si los tipos producidos por el proyecto core han cambiado (es decir, archivos .d.ts ). Esto significa que un cambio en el núcleo no implica un reensamblaje global de todos los proyectos. Por esta razón, establecer el indicador composite también provoca la configuración del indicador de declaration .

- Modo de construcción


TypeScript 3.0 introducirá un conjunto de API para referencias de proyectos para que otras herramientas puedan proporcionar este método de construcción incremental rápido. En particular, el complemento gulp-typescript ya usa estas API. Por lo tanto, los enlaces posteriores a los proyectos se integrarán con los orquestadores de ensamblaje que elija.

Sin embargo, para muchas aplicaciones y bibliotecas simples, es aconsejable no usar herramientas externas. Esta es la razón por la cual el comando tsc ahora establece una nueva bandera --build .

El tsc --build (o su alias, tsc -b ) toma un conjunto de proyectos y los construye, así como también proyectos dependientes. Cuando se usa el nuevo modo de construcción, en primer lugar, se debe establecer el indicador --build , y se puede combinar con algunos otros indicadores:
  • --verbose : muestra cada paso requerido por el proceso de construcción.
  • --dry : --dry sin generar archivos de salida (útil junto con la opción --verbose ).
  • –clean : –clean eliminar archivos de salida que coinciden con la entrada especificada.
  • --force : --force compilación completa y no incremental del proyecto.

Gestión de estructura de salida


Una ventaja sutil pero increíblemente útil de las referencias de proyectos es la capacidad lógica de asignar archivos de entrada a los archivos de salida correspondientes.

Si alguna vez ha intentado separar las partes cliente y servidor de la aplicación, es posible que tenga problemas para administrar la estructura de salida.

Por ejemplo, si tanto client / index.ts como server / index.ts se refieren a shared / index.ts para los siguientes proyectos:



... cuando intentamos construir proyectos de cliente y servidor, obtenemos ...



... no ...



Tenga en cuenta que después de la compilación, recibimos copias de la carpeta compartida tanto en el cliente como en el servidor. Dedicamos más tiempo a construir el ensamblado compartido dos veces y agregamos un nivel indeseable de anidamiento a lib / client / client y lib / server / server.

El problema es que TypeScript busca ansiosamente archivos .ts e intenta incluirlos en esta compilación. Idealmente, TypeScript debería haber entendido que estos archivos no deberían participar en el ensamblaje en la misma compilación y, en su lugar, ir a los archivos .d.ts para obtener información sobre el tipo.

La creación del archivo tsconfig.json para shared produce exactamente este resultado. Señala al compilador TypeScript:

  1. que el proyecto compartido debe construirse independientemente
  2. y que al importar desde ../shared debemos buscar archivos .d.ts en su directorio de salida.

Esto evita ejecutar un ensamblaje doble, además de incluir accidentalmente todo el contenido compartido.

Planes futuros


Para obtener una comprensión más profunda de los enlaces de diseño y las posibilidades de su uso, lea sobre ellos con más detalle en el rastreador de esta versión . En un futuro cercano, prepararemos la documentación sobre los enlaces del proyecto y el modo de construcción.

Nos esforzamos para que los autores de otras herramientas de programación puedan mantener referencias a proyectos y continuar mejorando el entorno de edición con respecto a esta función. Tenemos la intención de asegurarnos de que trabajar con enlaces de proyectos funcione tan bien como desarrollar código con un solo archivo tsconfig.json. Si eventualmente comienza a usar enlaces de proyectos, le agradeceremos sus comentarios.

Recuperando y distribuyendo listas de parámetros usando tuplas


A menudo damos esto por sentado, pero JavaScript nos permite considerar las listas de parámetros como valores de primera clase, ya sea utilizando argumentos o parámetros de tipo rest (por ejemplo ... rest).

 function call(fn, ...args) { return fn(...args); } 

Tenga en cuenta que call funciona para funciones con cualquier número de parámetros. A diferencia de otros lenguajes, JavaScript no nos obliga a definir call0, call1, call2, etc. de la siguiente manera:

 function call0(fn) { return fn(); } function call1(fn, param1) { return fn(param1); } function call2(fn, param1, param2) { return fn(param1, param2); } function call3(fn, param1, param2, param3) { return fn(param1, param2, param3); } 

Desafortunadamente, durante algún tiempo no hubo una buena manera de expresar esto en TypeScript sin declarar un número finito de sobrecargas:

 // TODO (billg): 5 overloads should *probably* be enough for anybody? function call<T1, T2, T3, T4, R>(fn: (param1: T1, param2: T2, param3: T3, param4: T4) => R, param1: T1, param2: T2, param3: T3, param4: T4): R function call<T1, T2, T3, R>(fn: (param1: T1, param2: T2, param3: T3) => R, param1: T1, param2: T2, param3: T3): R function call<T1, T2, R>(fn: (param1: T1, param2: T2) => R, param1: T1, param2: T2): R function call<T1, R>(fn: (param1: T1) => R, param1: T1): R; function call<R>(fn: () => R, param1: T1): R; function call(fn: (...args: any[]) => any, ...args: any[]) { return fn(...args); } 

Uf! ¡Otra muerte con mil sobrecargas! O al menos tantas sobrecargas como necesiten los usuarios.

TypeScript 3.0 le permite simular mejor tales escenarios, ya que ahora los parámetros del tipo de resto pueden ser universales, y su tipo se define como una tupla. En lugar de declarar cada una de estas sobrecargas, decimos que el parámetro rest ... args de la función fn debería ser un parámetro de tipo que extienda la matriz, y luego reutilizarlo para el parámetro ... args que pasa la función de llamada:

 function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); } 

Cuando llamamos a la función de llamada, TypeScript intenta extraer una lista de parámetros de lo que pasamos a fn y convertirla en una tupla:

 function foo(x: number, y: string): string { return (x + y).toLowerCase(); } // The `TS` type parameter is inferred as `[number, string]` call(foo, 100, "hello"); 

Cuando TypeScript define TS como [número, cadena], y terminamos de reutilizar TS en el parámetro rest de la función de llamada, la instancia de la función se ve así:

 function call(fn: (...args: [number, string]) => string, ...args: [number, string]): string 

¡Y en TypeScript 3.0, cuando se usa una tupla en reposo, el parámetro se minimiza al resto de la lista de parámetros! La instancia anterior se reduce a parámetros simples sin tuplas:

 function call(fn: (arg1: number, arg2: string) => string, arg1: number, arg2: string): string 

Entonces, además de detectar errores de conversión de tipo al pasar argumentos no válidos:

 function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); } call((x: number, y: string) => y, "hello", "world"); // ~~~~~~~ // Error! `string` isn't assignable to `number`! 

... y escriba la definición de otros argumentos:

 call((x, y) => { /* .... */ }, "hello", 100); // ^ ^ // `x` and `y` have their types inferred as `string` and `number` respectively. 

... también podemos ver los tipos de tuplas que estas funciones definen desde el exterior:

 function tuple<TS extends any[]>(...xs: TS): TS { return xs; } let x = tuple(1, 2, "hello"); // has type `[number, number, string]` 

Pero presta atención a una advertencia. Para hacer todo este trabajo, tuvimos que ampliar las capacidades de las tuplas ...

Nuevas características de tipo Tuple


Para modelar la lista de parámetros como una tupla (como acabamos de comentar), tuvimos que repensar un poco los tipos de tupla. Antes del lanzamiento de TypeScript 3.0, lo mejor que se podía modelar usando tuplas era el orden y la longitud del conjunto de parámetros.

Sin embargo, las listas de parámetros no son solo listas de tipos ordenados. Por ejemplo, los parámetros al final pueden ser opcionales:

 // Both `y` and `z` are optional here. function foo(x: boolean, y = 100, z?: string) { // ... } foo(true); foo(true, undefined, "hello"); foo(true, 200); 

El último parámetro puede ser un parámetro de reposo.

 // `rest` accepts any number of strings - even none! function foo(...rest: string[]) { // ... } foo(); foo("hello"); foo("hello", "world"); 

Y finalmente, hay una propiedad bastante interesante de las listas de parámetros: pueden estar vacías:

 // Accepts no parameters. function foo() { // ... } foo(); 

Por lo tanto, para que las tuplas se correspondan con las listas de parámetros, necesitamos simular cada uno de estos escenarios.

En primer lugar, ahora al final de la tupla puede haber elementos opcionales:

 /** * 2D, or potentially 3D, coordinate. */ type Coordinate = [number, number, number?]; 

El tipo Coordinate crea una tupla con una propiedad opcional llamada 2: ¡un elemento con índice 2 puede no estar definido! Curiosamente, dado que las tuplas usan un tipo literal numérico para su propiedad de longitud, la propiedad de longitud de la tupla Coodinate es de tipo 2 | 3)

En segundo lugar, el elemento de descanso ahora puede estar presente al final de la tupla.

 type OneNumberAndSomeStrings = [number, ...string[]]; 

Gracias a los elementos de descanso, las tuplas exhiben un comportamiento "ilimitado desde el final" muy interesante. El ejemplo anterior de tipo OneNumberAndSomeStrings requiere que el tipo de su primera propiedad sea número, y se permiten una o más propiedades de tipo cadena. La indexación de este tipo de tupla con un número de número arbitrario devuelve la cadena de tipo | número, porque el valor del índice es desconocido. De manera similar, dado que la longitud de la tupla es desconocida, el valor de la propiedad de longitud es simplemente número.

Cabe señalar que, en ausencia de otros elementos, el elemento de descanso en la tupla es idéntico a sí mismo:

 type Foo = [...number[]]; // Equivalent to `number[]`. 

¡Finalmente, las tuplas ahora pueden estar vacías! Aunque esto no es muy útil cuando se usa fuera de las listas de parámetros, un tipo de tupla vacío se puede definir como []:

 type EmptyTuple = []; 

Como es de esperar, una tupla vacía tiene una propiedad de longitud de 0, y la indexación con número devuelve el tipo nunca.

Diagnóstico de errores y entorno de usuario mejorados


Con el tiempo, recibimos más y más solicitudes de miembros de nuestra comunidad con respecto a la mejora de los mensajes de error. Aunque este trabajo está lejos de estar completo, nos enteramos de usted e hicimos una serie de mejoras en la versión TypeScript 3.0.

Rangos de error asociados


En parte, el objetivo de un buen mensaje de error es indicar al usuario cómo corregirlo o, en primer lugar, dejar claro por qué apareció este mensaje. En la mayoría de los casos, contiene mucha información o indica varias razones para que ocurra. A partir de un análisis de estas razones, podemos concluir que los errores resultan de diferentes partes del código.

Los rangos de error asociados son una nueva forma de proporcionar esta información a los usuarios. En TypeScript 3.0, los mensajes de error pueden generar mensajes en otra parte del código para que los usuarios puedan descubrir la causa y el efecto del error.



En cierto sentido, los mensajes de error relacionados no solo pueden dar una explicación al usuario, sino que también indican la ruta al lugar donde todo salió mal.



¡Estos intervalos también aparecerán en modo terminal cuando ejecute el comando tsc con el modo --pretty habilitado, aunque todavía estamos trabajando para mejorar la interfaz de usuario y considerar sus comentarios!

Diagnóstico mejorado y manejo de errores


Al prepararnos para el lanzamiento de TypeScript 2.9, comenzamos a prestar más atención a los mensajes de error, y en el lanzamiento 3.0 realmente intentamos resolver las tareas principales que nos permitirían realizar un diagnóstico de errores inteligente, claro y preciso. Esto incluye, en particular, la selección de tipos apropiados en caso de inconsistencias en los tipos de asociación y la salida directa a la fuente del error para ciertos tipos de mensajes.

Creemos que nuestros esfuerzos se han justificado y, como resultado, recibirá mensajes de error más cortos y claros.





Tipo desconocido


El tipo any es cualquier tipo en TypeScript que sea adecuado para cualquier cosa. Como cubre los tipos de todos los valores posibles, no nos obliga a hacer ninguna verificación antes de intentar llamar, construir o acceder a sus propiedades. También le permite asignar valores de tipo any a variables que esperan valores de cualquier otro tipo.

Esta característica es generalmente útil, pero no puede proporcionar suficiente rigor.

 let foo: any = 10; // All of these will throw errors, but TypeScript // won't complain since `foo` has the type `any`. foo.x.prop; foo.y.prop; foo.z.prop; foo(); new foo(); upperCase(foo); foo `hello world!`; function upperCase(x: string) { return x.toUpperCase(); } 

A veces, en TypeScript, desea describir un tipo que no es adecuado para nada. Esto es útil para una API que quiere señalar: "Puede ser cualquier valor, por lo que debe hacer algunas comprobaciones antes de usarlo". Y los usuarios se ven obligados a analizar los valores de retorno por razones de seguridad.

TypeScript 3.0 introduce un nuevo tipo llamado desconocido, que hace exactamente eso. any, unknown , , any, unknown . unknown, .

unknown any, foo :

 let foo: unknown = 10; // Since `foo` has type `unknown`, TypeScript // errors on each of these locations. foo.x.prop; foo.y.prop; foo.z.prop; foo(); new foo(); upperCase(foo); foo `hello world!`; function upperCase(x: string) { return x.toUpperCase(); } 

, , , .

 let foo: unknown = 10; function hasXYZ(obj: any): obj is { x: any, y: any, z: any } { return !!obj && typeof obj === "object" && "x" in obj && "y" in obj && "z" in obj } // Using a user-defined type guard... if (hasXYZ(foo)) { // ...we're allowed to access certain properties again. foo.x.prop; foo.y.prop; foo.z.prop; } // We can also just convince TypeScript we know what we're doing // by using a type assertion. upperCase(foo as string); function upperCase(x: string) { return x.toUpperCase(); } 

: , , , {} | null | undefined, unknown , :

 type Arrayify<T> = T extends any ? Array<T> : never; type A = Arrayify<{} | null | undefined>; // null[] | undefined[] | {}[] type B = Arrayify<unknown>; // unknown[] 

defaultProps JSX


: .d.ts React , , .

- TypeScript/JavaScript , , . , . , .

 function loudlyGreet(name = "world") { // Thanks to the default initializer, `name` will always have type `string` internally. // We don't have to check for `undefined` here. console.log("HELLO", name.toUpperCase()); } // Externally, `name` is optional, and we can potentially pass `undefined` or omit it entirely. loudlyGreet(); loudlyGreet(undefined); 

React (props). React , defaultProps, props.

 // Some non-TypeScript JSX file import * as React from "react"; import * as ReactDOM from "react-dom"; export class Greet extends React.Component { render() { const { name } = this.props; return <div>Hello ${name.toUpperCase()}!</div>; } static defaultProps = { name: "world", }; } // Notice no `name` attribute was specified! // vvvvvvvvv const result = ReactDOM.renderToString(<Greet />); console.log(result); 

, <Greet /> name. Greet, name «world», : Hello world!.

, TypeScript , defaultProps - JSX. render:

 export interface Props { name?: string } export class Greet extends React.Component<Props> { render() { const { name } = this.props; // Notice the `!` ------v return <div>Hello ${name!.toUpperCase()}!</div>; } static defaultProps = { name: "world"} } 

, .

TypeScript 3.0 JSX, LibraryManagedAttributes. , , TypeScript, JSX. , , React defaultProps , , propTypes.

 export interface Props { name: string } export class Greet extends React.Component<Props> { render() { const { name } = this.props; return <div>Hello ${name.toUpperCase()}!</div>; } static defaultProps = { name: "world"} } // Type-checks! No type assertions needed! let el = <Greet /> 

, . defaultProps, Partial , - (stateless function components, SFC), defaultProps Partial , . defaultProps (. ) SFC ES2015:

 function Greet({ name = "world" }: Props) { return <div>Hello ${name.toUpperCase()}!</div>; } 

, . TypeScript, .d.ts DefinitelyTyped , , @types/react . DefinitelyTyped, .

/// <reference lib="..." />


, , , (polyfills) — , API , ( .d.ts), API. , TypeScript lib.d.ts , --lib --target. , core-js lib.es2015.d.ts.

TypeScript 3.0 , API, , : /// <reference lib="..." />.

, Promise ES2015

 /// <reference lib="es2015.promise" /> export {}; 

, TypeScript 3.0 , lib.es2015.promise.d.ts, , Promise .


, , TypeScript , . TypeScript JavaScript , Visual Studio, Visual Studio Code TypeScript. , , , Go to Definition (« ») . TypeScript 3.0 .


, , .

 import * as dependency from "./dependency"; // look at all this repetition! dependency.foo(); dependency.bar(); dependency.baz(); 

, , , , .

 import { foo, bar, baz } from "./dependency"; // way lower in the file... foo(); bar(); baz(); 

, , . TypeScript 3.0 , .




TypeScript , JSX:

  • JSX;
  • JSX.




TypeScript — , .


, API .

, TypeScript 3 , . , API .

unknown —


unknown — , , , .

API


  • LanguageService#getSourceFile , . . #24540 .
  • TypeChecker#getSymbolDisplayBuilder . . #25331 . emitter ( ) node builder.
  • escapeIdentifier unescapeIdentifier . API , . , , . escapeLeadingUnderscores unescapeLeadingUnderscores, , ( «» __String string ).
  • TypeChecker#getSuggestionForNonexistentProperty, TypeChecker#getSuggestionForNonexistentSymbol TypeChecker#getSuggestionForNonexistentModule , API. . #25520 .

Perspectivas


TypeScript . , , , DefinitelyTyped , . , .

, TypeScript ( , ). , , JavaScript. , TypeScript, .

, , , , , Twitter . .

, TypeScript, ! . , , TypeScript , .

!
TypeScript

Source: https://habr.com/ru/post/es420761/


All Articles