lib.d.ts
Когда вы устанавливаете TypeScript, вместе с ним устанавливаются файлы объявлений, такие как lib.d.ts
. Этот файл содержит различные объявления общей среды, которые существуют во время выполнения JavaScript и DOM.
Он автоматически включается в контекст компиляции проекта TypeScript;
Это позволяет быстро начать писать типизированный JavaScript.
Вы можете исключить этот файл из контекста, указав флаг командной строки компилятора --noLib
(или указав параметр noLib: true
в tsconfig.json
).
Пример использования
Посмотрите на следующий пример:
const foo = 123;
const bar = foo.toString();
Этот тип кода работает нормально, потому что lib.d.ts
определяет метод toString
для всех объектов JavaScript.
Если вы используете тот же код с опцией noLib
, это приведет к ошибке проверки типа:
const foo = 123;
const bar = foo.toString(); // ERROR: Property 'toString' does not exist on type 'number'
Теперь, когда вы понимаете важность lib.d.ts
для ее содержания, давайте объясним следующее.
Заглянем внутрь lib.d.ts
lib.d.ts
Содержимое lib.d.ts
- это в основном объявления переменных (такие как: window
, document
, math
) и некоторые аналогичные объявления интерфейса (такие как: Window
, Document
, Math
).
Самый простой способ найти типы кода (такие как Math.floor
) - это использовать F12
(для mac fn
+ F12
) из IDE (переход к определению).
Давайте посмотрим на объявление примерной переменной, поскольку window
определяется как:
declare var window: Window;
Это просто declate var
, за которым следуют имя переменной (window
) и интерфейс для аннотаций типов (интерфейс Window
). Эти переменные обычно указывают на некоторый глобальный интерфейс. Например, ниже приведена небольшая часть интерфейса Window
:
interface Window
extends EventTarget,
WindowTimers,
WindowSessionStorage,
WindowLocalStorage,
WindowConsole,
GlobalEventHandlers,
IDBEnvironment,
WindowBase64 {
animationStartTime: number;
applicationCache: ApplicationCache;
clientInformation: Navigator;
closed: boolean;
crypto: Crypto;
// so on and so forth...
}
Вы можете видеть много информации о типах в этих интерфейсах. Когда вы не используете TypeScript, вам нужно хранить их в своем мозгу. Теперь вы можете использовать такие вещи, как intellisense
, которые позволят запоминать что-то более важное.
Выгодно использовать эти глобальные переменные. Позволяет добавлять дополнительные свойства без изменения lib.d.ts
. Далее мы покажем эти понятия.
Изменение исходных типов
В TypeScript интерфейсы открыты, что означает, что когда вы хотите использовать несуществующие члены, вам просто нужно добавить их в объявление интерфейса в lib.d.ts
, и TypeScript автоматически получит его. Обратите внимание, что вам нужно внести эти изменения в глобальный модуль, чтобы связать эти интерфейсы с lib.d.ts
. Мы рекомендуем вам создать специальный файл с именем global.d.ts
.
Вот несколько примеров, как мы можем добавить новые свойства в Window
, Math
, Date
:
Window
Просто добавлено свойство для интерфейса Window
interface Window {
helloWorld(): void;
}
Это позволит вам использовать его безопасным способом:
// Добавьте в код
window.helloWorld = () => console.log('hello world');
// Вызовите
window.helloWorld();
// Неправильное использование может привести к ошибкам
window.helloWorld('gracius'); // Error: Supplied parameters do not match the signature of the call target
Math
Глобальная переменная Math
определена в lib.d.ts
как:
/** An intrinsic object that provides basic mathematics functionality and constants. */
declare var Math: Math;
То есть переменная Math
является экземпляром Math
, а интерфейс Math
определяется как:
interface Math {
E: number;
LN10: number;
// others ...
}
Когда вы хотите добавить атрибуты, которые вам нужны, в глобальную переменную Math
, вам нужно только добавить его в глобальный интерфейс Math
. Например, в seedrandom Project
, он добавляет функцию seedrandom
в глобальный объект Math. Это можно сделать так:
interface Math {
seedrandom(seed?: string): void;
}
А затем использовать это так:
Math.seedrandom();
Math.seedrandom('Any string you want');
Date
Если вы ищете объявление определения Date
в lib.d.ts
, вы найдете:
declare var Date: DateConstructor;
Интерфейс DateConstructor
такой же, как интерфейсы Math
и Window
, которые вы видели выше, поскольку он охватывает элементы глобальной переменной Date
, которые можно использовать (например, Date.now()
). Кроме того, он содержит подпись для конструктора (например, new Date()
), которая позволяет создавать экземпляр Date
. Часть кода для интерфейса DateConstructor
выглядит следующим образом:
interface DateConstructor {
new (): Date;
// ... other construct signatures
now(): number;
// ... other member functions
}
В datejs добавляют свойства как к глобальной переменной Date
, так и к экземплярам Date
, поэтому определение TypeScript этой библиотеки выглядит следующим образом (сообщество уже определило его)
// DateJS добавил статические методы
interface DateConstructor {
/** Gets a date that is set to the current date. The time is set to the start of the day (00:00 or 12:00 AM) */
today(): Date;
// ... so on and so forth
}
// DateJS дал доступ к публичным методам
interface Date {
/** Adds the specified number of milliseconds to this instance. */
addMilliseconds(milliseconds: number): Date;
// ... so on and so forth
}
Это позволяет вам делать это с проверкой типов:
const today = Date.today();
const todayAfter1second = today.addMilliseconds(1000);
string
Если вы ищете string
в lib.d.ts
, вы найдете что-то похожее на Date
(глобальные переменные String
, интерфейс StringConstructor
, интерфейс String
). Но стоит отметить, что интерфейс String
также влияет на строковые литералы, как показано ниже:
interface String {
endsWith(suffix: string): boolean;
}
String.prototype.endsWith = function(suffix: string): boolean {
const str: string = this;
return str && str.indexOf(suffix, str.length - suffix.length) !== -1;
};
console.log('foo bar'.endsWith('bas')); // false
console.log('foo bas'.endsWith('bas')); // true
string redux
Для удобства объявления мы рекомендуем создать файл global.d.ts
. Тем не менее, если вы хотите, вы можете войти в глобальное пространство имен из файлового модуля, используя declare global { / global namespace / }
:
// Убедитесь, что это модуль
export {};
declare global {
interface String {
endsWith(suffix: string): boolean;
}
}
String.prototype.endsWith = function(suffix: string): boolean {
const str: string = this;
return str && str.indexOf(suffix, str.length - suffix.length) !== -1;
};
console.log('foo bar'.endsWith('bas')); // false
console.log('foo bas'.endsWith('bas')); // true
Используйте свой собственный lib.d.ts
lib.d.ts
Как упоминалось выше, использование параметра компиляции --noLib
приведет к тому, что TypeScript автоматически исключит включенные файлы lib.d.ts
. Почему эта функция работает, я перечислил несколько общих причин:
Рабочая среда JavaScript сильно отличается от стандартной среды выполнения на основе браузера;
Вы хотите строго контролировать глобальные переменные в своем коде, например:
lib.d.ts
определяет элемент как глобальную переменную, и вы не хотите, чтобы он просочился в ваш код.
После исключения файла lib.d.ts
по умолчанию вы можете включить файл с аналогичным именем в контекст компиляции, и TypeScript выберет его для проверки типа.
Влияние target компилятора на lib.d.ts
lib.d.ts
Установка target
компиляции в es6
может привести к тому, что lib.d.ts
будет включать в себя более современные (es6
) объявления среды, такие как Promise
. Этот волшебный эффект целей компилятора изменяет среду кода, которая идеально подходит для некоторых людей, но вызывает путаницу у других, потому что смешивает скомпилированный код со средой.
Если вам нужен более детальный контроль над вашей средой, вы должны использовать параметр --lib
, который мы обсудим далее.
--lib
опция
--lib
опцияИногда вы хотите отделить связь между целью компиляции (созданная версия JavaScript) и поддержкой окружающих библиотек. Например, для Promise
вашей целью компиляции является --target es5
, но вы все равно хотите ее использовать. В настоящее время вы можете использовать lib
для управления ею.
Вы можете предоставить эту опцию компилятору из командной строки или в tsconfig.json
(рекомендуется):
Командная строка
tsc --target es5 --lib dom,es6
config.json
"compilerOptions": {
"lib": ["dom", "es6"]
}
lib
может быть классифицированы следующим образом:
JavaScript
es5
es6
es2015
es7
es2016
es2017
esnext
Runtime Environment
dom
dom.iterable
webworker
scripthost
ESNext Варианты функций
es2015.core
es2015.collection
es2015.generator
es2015.iterable
es2015.promise
es2015.proxy
es2015.reflect
es2015.symbol
es2015.symbol.wellknown
es2016.array.include
es2017.object
es2017.sharedmemory
esnext.asynciterable
Моя личная рекомендация:
"compilerOptions": {
"target": "es5",
"lib": ["es6", "dom"]
}
Включает ES5 с использованием Symbol:
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom", "scripthost", "es2015.symbol"]
}
Polyfill при использовании старых движков JavaScript
Чтобы использовать некоторые новые функции, такие как Map
, Set
, Promise
(которые будут меняться со временем), вы можете использовать современные опции lib
и вам нужно установить core-js
:
npm install core-js --save-dev
Затем импортируйте его в свой проект:
import 'core-js';
Last updated
Was this helpful?