Trabalhando com Arquivos de Declaração em TypeScript
Para estabelecer a conexão com arquivos de scripts JavaScript externos em TypeScript (TS), utilizamos arquivos de declaração ou de cabeçalho. Esses arquivos possuem a extensão .d.ts e descrevem a sintaxe e a estrutura de funções e propriedades que podem ser usadas no programa, sem fornecer uma implementação concreta. Seu funcionamento é semelhante ao dos arquivos com extensão .h em linguagens como C/C++. Eles atuam como uma camada de encapsulamento sobre bibliotecas JavaScript.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Programício</title>
  </head>
  <body>
    <h2>Aplicação em TypeScript</h2>
    <script>
      let message = "Hello TypeScript!";
    </script>
    <script src="app.js"></script>
  </body>
</html>Neste caso, para simplificar, a variável message é definida na própria página web, embora também pudesse ser definida em um arquivo JS externo.
Suponha que queremos usar essa variável message no código TypeScript no arquivo app.ts:
console.log(message);Ao executar a aplicação, o compilador TS não conseguirá compilar o programa, pois, para o código TypeScript, a variável global ainda não existe. Isso ocorre porque o compilador do TypeScript exige que todas as variáveis estejam explicitamente declaradas e tipadas no próprio código TypeScript. Esse comportamento está alinhado aos princípios do TypeScript, que visam garantir maior segurança e previsibilidade no código.
Para resolver esse problema, é necessário incluir a definição da variável global utilizando arquivos de declaração. Para isso, devemos adicionar ao projeto um novo arquivo chamado globals.d.ts com o seguinte conteúdo:
declare let message: string;Com a palavra-chave declare, incluímos a definição da variável global no programa TS.
Assim, teremos a seguinte estrutura de projeto:
. ├── app.ts ├── globals.d.ts └── index.html
Compilação
Se compilarmos passando o nome do arquivo ao compilador no console:
tsc app.ts
Neste caso, o compilador não encontrará automaticamente o arquivo globals.d.ts. Precisamos, então, especificar explicitamente a localização do arquivo globals.d.ts no arquivo app.ts usando a diretiva reference:
/// <reference path="globals.d.ts" />
console.log(message);
Se confiarmos no arquivo de configuração tsconfig.json, executando simplesmente o comando:
tsc
Neste caso, não é necessário especificar a diretiva /// <reference path="globals.d.ts" />.
Da mesma forma, podemos incluir outros componentes do código JavaScript — funções, objetos e classes. Vamos examinar como fazê-lo.
Funções
Suponha que, no código JS de uma página web, estejam declaradas as seguintes funções:
let message = "Hello TypeScript!";
function hello() {
  console.log(message);
}
function sum(a, b) {
  return a + b;
}A função hello() exibe o valor da variável message no console, e a função sum() retorna a soma de dois números.
E suponha que, no código TS, queremos chamar essas funções:
hello();
let result = sum(2, 5);
console.log(result);Nesse caso, a inclusão no arquivo globals.d.ts ficaria assim:
declare function hello(): void;
declare function sum(a: number, b: number): number;Objetos
Suponha que, no código JavaScript, exista o seguinte objeto:
const tom = {
  name: "Tom",
  age: 37,
  print() {
    console.log(`Name: ${this.name}  Age: ${this.age}`);
  },
};Vamos usar esse objeto no código TypeScript:
tom.print();Nesse caso, a definição do objeto no arquivo globals.d.ts seria:
declare const tom: { name: string; age: number; print: () => void };Array de Objetos
Pode haver dificuldades ao incluir arrays de objetos. Por exemplo, suponha que haja o seguinte objeto JavaScript:
var points = [
  { X: 10, Y: 34 },
  { X: 24, Y: 65 },
  { X: 89, Y: 12 },
];Para esse array de objetos, no arquivo globals.d.ts, podemos definir uma interface correspondente a cada objeto individual e incluir um array de objetos dessa interface, que contém duas propriedades X e Y:
interface IPoint {
  X: number;
  Y: number;
}
declare var points: IPoint[];E no TypeScript poderemos usar esse array:
for (let point of points) {
  console.log(`Ponto com coordenadas X =
      ${point.X} Y = ${point.Y}`);
}Saída no console do navegador:
Ponto com coordenadas X = 10 Y = 34 Ponto com coordenadas X = 24 Y = 65 Ponto com coordenadas X = 89 Y = 12
Classes
Vamos considerar mais um exemplo: incluir em TypeScript classes definidas em JavaScript. Suponha que, no código JavaScript, seja definida a seguinte classe Person:
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  display() {
    console.log(this.name, this.age);
  }
}Para essa classe, no arquivo globals.d.ts, definimos a seguinte declaração de classe:
declare class Person {
  name: string;
  age: number;
  constructor(name: string, age: number);
  display(): void;
}Especificamos todos os campos e métodos da classe; os métodos (incluindo o construtor) não têm implementação: apenas definimos os parâmetros, seus tipos e o tipo do valor retornado.
E no código TypeScript usamos essa classe:
let tom = new Person("Tom", 37);
tom.display(); // Tom 37
console.log(tom.name); // Tom