TypeScript 3.0

TypeScript 3.0! Sim, ele saiu, e realmente tem muitas inovações. Abaixo do corte, você encontrará uma descrição detalhada de todas as inovações mais recentes, incluindo o modo de compilação, um novo tipo desconhecido, alterações significativas na API, melhorias de desempenho e muito mais. Inscreva-se agora!



Lançamento do TypeScript 3.0! Um novo marco começou no caminho para o desenvolvimento do TypeScript, um assistente para todos os usuários de JavaScript.

Se você não está familiarizado com o TypeScript, não é tarde demais para aprender sobre isso agora! O TypeScript é uma extensão JavaScript projetada para uso na versão moderna dessa linguagem de tipos estáticos. O compilador TypeScript lê o código TypeScript, que contém, em particular, declarações de tipo e anotações de tipo, e produz código JavaScript limpo e de fácil leitura, no qual essas construções são transformadas e excluídas. O código resultante é executado em qualquer ambiente de tempo de execução que esteja em conformidade com o padrão ECMAScript, por exemplo, em seu navegador favorito ou na plataforma do servidor Node.js.

Usar esse ambiente significa que o código será analisado quanto a erros ou erros de digitação antes de ser lançado pelos usuários, mas suas vantagens não se limitam a isso. Com todas essas informações e resultados de análise, o TimeScript aprimora a usabilidade, fornecendo ferramentas de preenchimento automático de código e navegação, como Localizar todas as referências, Ir para definição e renomear no seu editor favorito. .

Para começar o idioma e obter mais informações, siga o link . Se você quiser experimentar o TypeScript 3.0 agora, baixe-o do NuGet ou via npm digitando

npm install -g typescript 

Além disso, o suporte está disponível nos seguintes editores:


Outros editores são atualizados de acordo com sua própria programação, mas em breve todos terão excelente suporte ao TypeScript.

Visão geral da versão 3.0


Após o lançamento do TypeScript 2.0, fornecemos uma breve visão geral da contribuição das versões anteriores para seu estado atual. Entre os lançamentos do TypeScript 1.0 e 2.0, a linguagem inclui tipos de união, protetores de tipo, suporte para o moderno padrão ECMAScript, aliases de tipo, suporte JSX, tipos literais e polimórficos. Se você incluir tipos TypeScript 2.0 que não são nulos, análise do fluxo de controle, suporte para uniões com tags, esses tipos e um modelo simplificado para receber arquivos .d.ts , podemos dizer que esse período determinou completamente o básico Trabalho TypeScript.

Então, o que foi feito desde então? O que nos levou ao TypeScript 3.0, além dos novos recursos do padrão ECMAScript, como funções async / await assíncronas, geradores e o operador resto / propagação?

O TypeScript 2.1 se tornou a versão fundamental, que introduziu um modelo estático de metaprogramação em JavaScript. Solicitação de chave ( keyof ), acesso ao índice ( T[K] ) e tipos de objetos mapeados ( { [K in keyof T]: } T[K]} ) - esta é uma lista de ferramentas usadas para modelar com mais eficiência as bibliotecas React, Ember, Lodash e outros.

As versões TypeScript 2.2 e 2.3 introduziram suporte para modelos de classe mixin, o tipo de object (representando um objeto que não é primitivo) e os valores padrão para tipos genéricos. Esses recursos foram usados ​​em vários projetos, como material angular e polímero. Além disso, o TypeScript 2.3 introduziu a capacidade de ajustar this tipos, permitindo que a linguagem funcionasse bem com bibliotecas como o Vue, e o sinalizador checkJs foi checkJs para permitir a verificação de tipos nos arquivos JavaScript.

Os TypeScript 2.4 e 2.6 continuam a história de aumentar a severidade da verificação do tipo de função, associada a algumas das análises mais antigas do nosso sistema de tipos. O sinalizador --strictFunctionTypes foi introduzido, forçando a contravariância de parâmetros. Na liberação 2.7, a tendência ao rigor persistiu e foi expressa na validação em classes usando o sinalizador --strictPropertyInitialization .

O TypeScript 2.8 apresenta tipos condicionais, uma ferramenta poderosa para expressar estaticamente decisões baseadas em tipos, e a versão 2.9 generaliza o operador keyof e simplifica a importação de tipos.

E isso nos leva ao TypeScript 3.0! Apesar do novo número inteiro no número, pouco mudou na versão 3.0 (o que implica uma atualização muito fácil). Ele apresenta uma nova maneira flexível e escalável de estruturar projetos, novo e poderoso suporte para trabalhar com listas de parâmetros, novos tipos para fornecer verificações explícitas, suporte JSX aprimorado, significativamente mais diagnóstico de erro fácil de usar e muito mais.

Novidades


  • Links do Projeto
    • --build Modo de construção
    • Gerenciamento da estrutura de saída
    • Planos futuros
  • Recuperando e Distribuindo Listas de Parâmetros Usando Tuplas
  • Novos recursos do tipo tupla
  • Tipo unknown
  • Melhor diagnóstico de erro e ambiente do usuário
    • Intervalos de erro associados
    • Diagnóstico aprimorado e tratamento de erros
  • Suporte para a propriedade defaultProps em JSX
  • Diretivas /// <reference lib="..." />
  • Melhorando a velocidade do editor
    • Refatorando Instruções de Importação Nomeada
    • Fim da tag final e quadro de estrutura de tópicos
    • Correções rápidas para código inacessível e tags não utilizadas
  • Mudanças críticas
    • unknown é um nome de tipo reservado
    • Alterações críticas da API

Links do Projeto


Com bastante frequência, para criar uma biblioteca ou aplicativo, você precisa seguir várias etapas. Suponha que sua base de código contenha os diretórios src e test . Suponha que você tenha uma pasta do client que o código da parte do cliente do aplicativo esteja armazenada e uma pasta de servidor que contenha o código da parte do servidor na plataforma Node.js. Cada uma delas participe do código da pasta shared . Talvez você esteja usando o chamado “repositório único” e tenha muitos projetos que são complexamente dependentes um do outro.

Um dos recursos mais importantes em que trabalhamos ao lançar o TypeScript 3.0 foi chamado de "links do projeto" e foi projetado para simplificar o trabalho com esses scripts.

Graças aos links do projeto, alguns projetos TypeScript podem depender de outros. Em particular, os arquivos tsconfig.json podem fazer referência a outros arquivos tsconfig.json . A definição dessas dependências facilita a divisão do código em projetos menores, porque o compilador TypeScript (e suas ferramentas) têm a oportunidade de entender a ordem e a estrutura da montagem da saída. Isso significa que a montagem é mais rápida e é executada de forma incremental (em etapas), navegação transparente, edição e refatoração para vários projetos. Como o TypeScript 3.0 estabelece a base do projeto e fornece uma API, qualquer ferramenta de construção deve poder fornecer isso.

Como é isso?


Aqui está um arquivo tsconfig.json contendo links para projetos como um exemplo simples.

 // ./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" } ] } 

Possui dois novos campos: composite e references .

O campo de references simplesmente aponta para outros arquivos tsconfig.json (ou para as pastas em que estão contidos). Cada link aqui é simplesmente um objeto com um campo de path ("caminho") e informa ao compilador TypeScript que para criar este projeto, você deve primeiro criar outro projeto ao qual ele se refere.

Aparentemente, o campo composite tem a mesma importância. O campo composite garante que determinados parâmetros sejam ativados, permitindo que qualquer projeto que dependa disso faça referência a ele e inclua-o em construções incrementais. A capacidade de construir de forma inteligente e incremental é importante, pois uma das principais razões pelas quais você pode abandonar um projeto é a velocidade de construção.

Por exemplo, se o projeto front-end depende do projeto shared , e o shared depende do núcleo, nossas APIs relacionadas aos links do projeto ajudarão a determinar as alterações no núcleo, mas só serão coletadas compartilhadas novamente se os tipos produzidos pelo projeto core forem alterados (ou seja, arquivos .d.ts ). Isso significa que uma mudança no núcleo não implica uma remontagem global de todos os projetos. Por esse motivo, a configuração do sinalizador composite também causa a configuração do sinalizador de declaration .

- Modo de construção


O TypeScript 3.0 apresentará um conjunto de APIs para referências de projeto, para que outras ferramentas possam fornecer esse método rápido de criação incremental. Em particular, o plug-in gulp-typescript já usa essas APIs! Assim, links posteriores para projetos serão integrados aos orquestradores de montagem de sua escolha.

No entanto, para muitos aplicativos e bibliotecas simples, é aconselhável não usar ferramentas externas. É por isso que o comando tsc agora define um novo sinalizador --build .

O tsc --build (ou seu alias, tsc -b ) pega um conjunto de projetos e os constrói, além de criar projetos dependentes. Ao usar o novo modo de compilação, primeiro, o sinalizador --build deve ser definido e pode ser combinado com outros sinalizadores:
  • --verbose : mostra cada etapa exigida pelo processo de compilação.
  • --dry : --dry sem gerar arquivos de saída (útil em conjunto com a opção --verbose ).
  • –clean : –clean excluir arquivos de saída correspondentes à entrada especificada.
  • --force : --force completa e não incremental do projeto.

Gerenciamento da estrutura de saída


Uma vantagem sutil, mas incrivelmente útil das referências do projeto é a capacidade lógica de mapear os arquivos de entrada para os arquivos de saída correspondentes.

Se você já tentou separar as partes do cliente e do servidor do aplicativo, pode ter problemas ao gerenciar a estrutura de saída.

Por exemplo, se client / index.ts e server / index.ts fizerem referência a shared / index.ts para os seguintes projetos:



... quando tentamos criar projetos de clientes e servidores, obtemos ...



... não ...



Observe que, após a compilação, recebemos cópias da pasta compartilhada no cliente e no servidor. Nós gastamos tempo extra na construção do assembly compartilhado duas vezes e adicionamos um nível indesejável de aninhamento à lib / client / client e lib / server / server.

O problema é que o TypeScript procura ansiosamente por arquivos .ts e tenta incluí-los nesta compilação. Idealmente, o TypeScript deveria ter entendido que esses arquivos não deveriam participar do assembly na mesma compilação e, em vez disso, acessar os arquivos .d.ts para obter informações sobre o tipo.

Criar o arquivo tsconfig.json para compartilhado produz exatamente esse resultado. Ele sinaliza para o compilador TypeScript:

  1. que o projeto compartilhado deve ser construído independentemente
  2. e que ao importar de ../shared, devemos procurar arquivos .d.ts em seu diretório de saída.

Isso evita a execução de uma montagem dupla, além de incluir acidentalmente todo o conteúdo compartilhado.

Planos futuros


Para entender melhor os links de design e as possibilidades de uso, leia sobre eles com mais detalhes no rastreador desta versão . Em um futuro próximo, prepararemos a documentação sobre os links do projeto e o modo de compilação.

Nós nos esforçamos para que os autores de outras ferramentas de programação possam manter referências a projetos e continuar a melhorar o ambiente de edição em relação a essa função. Pretendemos garantir que o trabalho com os links do projeto seja executado tão facilmente quanto o desenvolvimento de código com um único arquivo tsconfig.json. Se você eventualmente começar a usar os links do projeto, ficaremos gratos por qualquer feedback.

Recuperando e Distribuindo Listas de Parâmetros Usando Tuplas


Costumamos tomar isso como garantido, mas o JavaScript nos permite considerar listas de parâmetros como valores de primeira classe - usando argumentos ou parâmetros do tipo rest (por exemplo ... rest).

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

Observe que a chamada funciona para funções com qualquer número de parâmetros. Ao contrário de outros idiomas, o JavaScript não nos obriga a definir chamada0, chamada1, chamada2 etc. da seguinte maneira:

 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); } 

Infelizmente, por algum tempo, não havia uma boa maneira de expressar isso no TypeScript sem declarar um 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); } 

Ufa! Outra morte com mil sobrecargas! Ou pelo menos quantas sobrecargas forem necessárias.

O TypeScript 3.0 permite simular melhor esses cenários, já que agora os parâmetros do tipo restante podem ser universais e seu tipo é definido como uma tupla. Em vez de declarar cada uma dessas sobrecargas, dizemos que o parâmetro rest ... args da função fn deve ser um parâmetro de tipo que estende a matriz e, em seguida, reutilize-o para o parâmetro ... args que a função de chamada passa:

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

Quando chamamos a função de chamada, o TypeScript tenta extrair uma lista de parâmetros do que passamos para fn e transformá-la em uma 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"); 

Quando o TypeScript define TS como [number, string], e terminamos de reutilizar o TS no parâmetro restante da função de chamada, a instância da função fica assim:

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

E no TypeScript 3.0, ao usar uma tupla em repouso, o parâmetro é minimizado para o restante da lista de parâmetros! A instância acima se resume a parâmetros simples sem tuplas:

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

Portanto, além de detectar erros de conversão de tipo ao transmitir argumentos invá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`! 

... e definição de tipo de outros argumentos:

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

... também podemos ver os tipos de tupla que essas funções definem de fora:

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

Mas preste atenção a uma ressalva. Para fazer todo esse trabalho, tivemos que expandir os recursos das tuplas ...

Novos recursos do tipo tupla


Para modelar a lista de parâmetros como uma tupla (como acabamos de discutir), tivemos que repensar um pouco os tipos de tupla. Antes do lançamento do TypeScript 3.0, o melhor que podia ser modelado usando tuplas era a ordem e o comprimento do conjunto de parâmetros.

No entanto, as listas de parâmetros não são apenas listas de tipos ordenados. Por exemplo, os parâmetros no final podem ser opcionais:

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

O último parâmetro pode ser um parâmetro de descanso.

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

E, finalmente, há uma propriedade bastante interessante das listas de parâmetros - elas podem estar vazias:

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

Portanto, para que as tuplas correspondam às listas de parâmetros, precisamos simular cada um desses cenários.

Em primeiro lugar, agora no final da tupla pode haver elementos opcionais:

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

O tipo de coordenada cria uma tupla com uma propriedade opcional denominada 2 - um elemento com o índice 2 pode não estar definido! Curiosamente, como as tuplas usam um tipo literal numérico para sua propriedade length, a propriedade length da tupla Coodinate é do tipo 2 | 3)

Em segundo lugar, o elemento restante agora pode estar presente no final da tupla.

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

Graças aos elementos restantes, as tuplas exibem um comportamento "ilimitado a partir do final" muito interessante. O exemplo acima do tipo OneNumberAndSomeStrings exige que o tipo de sua primeira propriedade seja number e uma ou mais propriedades do tipo string são permitidas. A indexação deste tipo de tupla com um número de número arbitrário retorna o tipo string | número, porque o valor do índice é desconhecido. Da mesma forma, como o comprimento da tupla é desconhecido, o valor da propriedade length é simplesmente number.

Deve-se notar que, na ausência de outros elementos, o elemento restante na tupla é idêntico a si mesmo:

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

Finalmente, as tuplas agora podem estar vazias! Embora isso não seja muito útil quando usado fora das listas de parâmetros, um tipo de tupla vazio pode ser definido como []:

 type EmptyTuple = []; 

Como seria de esperar, uma tupla vazia tem uma propriedade length igual a 0 e a indexação com número retorna o tipo nunca.

Melhor diagnóstico de erro e ambiente do usuário


Com o tempo, recebemos mais e mais solicitações de membros da nossa comunidade com relação à melhoria das mensagens de erro. Embora este trabalho esteja longe de terminar, ouvimos você e fizemos várias melhorias na versão TypeScript 3.0.

Intervalos de erro associados


Em parte, o objetivo de uma boa mensagem de erro é indicar ao usuário como corrigi-la ou, antes de tudo, deixar claro por que essa mensagem apareceu. Na maioria dos casos, contém muitas informações ou indica vários motivos para sua ocorrência. A partir de uma análise desses motivos, podemos concluir que os erros resultam de diferentes partes do código.

Os intervalos de erros associados são uma nova maneira de fornecer essas informações aos usuários. No TypeScript 3.0, as mensagens de erro podem gerar mensagens em outras partes do código, para que os usuários possam descobrir a causa e o efeito do erro.



Em certo sentido, as mensagens de erro relacionadas podem não apenas dar uma explicação ao usuário, mas também indicar o caminho para o local em que tudo deu errado.



Esses intervalos também aparecerão no modo terminal quando você executar o comando tsc com o modo --pretty ativado, apesar de ainda estarmos trabalhando para melhorar a interface do usuário e considerar seus comentários!

Diagnóstico aprimorado e tratamento de erros


Ao nos prepararmos para o lançamento do TypeScript 2.9, começamos a prestar mais atenção às mensagens de erro e, no release 3.0, realmente tentamos resolver as principais tarefas que nos permitiriam realizar um diagnóstico de erro inteligente, claro e preciso. Isso inclui, em particular, a seleção de tipos apropriados em caso de inconsistências nos tipos de associação e a saída diretamente para a fonte do erro para certos tipos de mensagens.

Acreditamos que nossos esforços foram justificados e, como resultado, você receberá mensagens de erro mais curtas e claras.





Tipo desconhecido


O tipo any é qualquer tipo no TypeScript adequado para qualquer coisa. Como abrange os tipos de todos os valores possíveis, não nos força a fazer nenhuma verificação antes de tentarmos chamar, construir ou acessar suas propriedades. Também permite atribuir valores do tipo any a variáveis ​​que esperam valores de qualquer outro tipo.

Esse recurso geralmente é útil, mas não pode fornecer rigor suficiente.

 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(); } 

Às vezes, no TypeScript, você deseja descrever um tipo que não é adequado para nada. Isso é útil para uma API que deseja sinalizar: "Pode ter qualquer valor, então você precisa fazer algumas verificações antes de usá-la." E os usuários são forçados a analisar valores de retorno por motivos de segurança.

O TypeScript 3.0 apresenta um novo tipo chamado desconhecido, que faz exatamente isso. 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/pt420761/


All Articles