Для установки связи с внешними файлами скриптов javascript в TS служат декларативные или заголовочные файлы. Это файлы с расширением .d.ts, они описывают синтаксис и структуру функций и свойств, которые могут использоваться в программе, не предоставляя при этом конкретной реализации. Их действие во многом похоже на работу файлов с расширением .h в языках C/C++. Они выполняют своего рода роль оберток над библиотеками JavaScript.
Рассмотрим, как мы можем использовать заголовочные файлы. Иногда в программах на javascript используются глобальные переменные, которые должны быть видны для всех функций приложения. Например, пусть на веб-странице (или во внешнем подключаемом файле javascript) в коде js определена переменная:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Metanit.com</title> </head> <body> <h2>Приложение на TypeScript</h2> <script> let message = "Hello TypeScript!"; </script> <script src="app.js"></script> </body> </html>
В данном случае для простоты переменная определена веб-странице, хотя она также могла быть определена во внешнем подключенном js-файле.
И, допустим, мы хотим использовать эту переменную message
в коде TypeScript в файле app.ts:
console.log(message);
При запуске приложения компилятор TS не сможет скомпилировать программу, так как для кода TS глобальная переменная пока не существует. В этом случае нам надо подключать определение глобальной переменной с помощью декларативных файлов. Для этого добавим в проект новый файл, который назовем globals.d.ts и который будет иметь следующее содержимое:
declare let message: string;
С помощью ключевого слова declare в программу на TS подключается определение глобальной переменной.
То есть у нас получится следующая структура проекта:
app.ts
globals.d.ts
index.html
Если мы компилируем, передавая компилятору в консоли название файла:
tsc app.ts
То в этом случае компилятор не найдет автоматически файл globals.d.ts. В этом случае нам надо в файле app.ts явно указать расположение файла globals.d.ts с помощью директивы reference
/// <reference path="globals.d.ts" /> console.log(message);
Если же мы полагаемся на файл конфигурации tsconfig.json, просто выполняя команду
tsc
то директиву /// <reference path="globals.d.ts" />
можно не указывать.
Подобным образом мы можем подключать другие компоненты кода JavaScript - функции, объекты, классы. Рассмотрим их подключение.
Пусть на веб-странице в коде js объявлены две следующие функции:
let message = "Hello TypeScript!"; function hello(){ console.log(message); } function sum(a, b){ return a + b; }
Функция hello()
выводит значение переменной message на консоль, а функция sum()
возвращает сумму двух чисел.
И, допустим, в коде TS мы хотим вызывать эти функции:
hello(); let result = sum(2, 5); console.log(result);
В этом случае подключение в файле globals.d.ts выглядело бы так:
declare function hello(): void; declare function sum(a: number, b: number): number;
Пусть в коде JavaScript есть следующий объект:
const tom = { name: "Tom", age: 37, print(){ console.log(`Name: ${this.name} Age: ${this.age}`); } }
Используем этот объект в коде typescript:
tom.print();
В этом случае определение объекта в файле globals.d.ts выглядело бы так:
declare const tom: {name: string, age: number, print: ()=> void};
Однако может возникнуть сложность с подключением более сложных объектов. Например, пусть есть такой объект javascript:
var points = [{ X: 10, Y: 34 }, { X: 24, Y: 65 }, { X: 89, Y: 12 }];
Для данного массива объектов в файле globals.d.ts мы можем определить соответствующий отдельному объекту интерфейс и подключить массив объектов некоторого интерфейса, который содержит два свойства X и Y:
interface IPoint { X: number; Y: number; } declare var points: IPoint[];
И в TS мы сможем использовать этот массив:
for (let point of points){ console.log(`Точка с координатами X = ${point.X} Y = ${point.Y}`); }
Консольный вывод браузера:
Рассмотрим последний пример - подключение в typescript классов, определенных в javascript. Пусть в коде JavaScript определен следующий класс Person:
class Person{ constructor(name, age){ this.name = name; this.age = age; } display(){ console.log(this.name, this.age); } }
Для этого класса в файле globals.d.ts определим следующее объявление класса:
declare class Person{ name: string; age: number; constructor(name: string, age: number); display(): void; }
Для класса прописываем все его поля и методы, при этом методы (в том числе конструктор) не имеют реализации, для них только определяются параметры и их типы и тип возвращаемого значения.
И в коде TypeScript используем этот класс:
let tom = new Person("Tom", 37); tom.display(); // Tom 37 console.log(tom.name); // Tom