Strict mode в TypeScript

Strict mode в TypeScript представляет собой набор строгих правил, направленных на улучшение качества кода и выявление потенциальных ошибок на этапе компиляции. Эти правила активно помогают разработчикам, снижая вероятность возникновения багов и улучшая читаемость и поддержку кода. Включение strict mode изменяет поведение компилятора, делая его более строгим к типам и различным аспектам работы с кодом.

Включение strict mode

Для того чтобы включить строгий режим в TypeScript, достаточно установить опцию "strict": true в конфигурационном файле tsconfig.json. Когда эта опция активирована, TypeScript включает несколько дополнительных проверок, которые позволяют значительно улучшить качество кода.

{
  "compilerOptions": {
    "strict": true
  }
}

Активировав "strict": true, автоматически включаются несколько подопций, таких как:

  • "noImplicitAny"
  • "noImplicitThis"
  • "alwaysStrict"
  • "strictNullChecks"
  • "strictFunctionTypes"
  • "strictBindCallApply"
  • "esModuleInterop"
  • "skipLibCheck"
  • "forceConsistentCasingInFileNames"

Каждая из этих опций направлена на то, чтобы улучшить работу с типами, предотвратить неявные ошибки и повысить безопасность кода.

Основные опции strict mode

noImplicitAny

Одна из наиболее важных опций в строгом режиме — это noImplicitAny. Включение этой опции заставляет TypeScript генерировать ошибку, если компилятор не может вывести тип для переменной или параметра, и в противном случае присваивает ему тип any.

function add(a, b) {
  return a + b;
}

Без noImplicitAny компилятор может разрешить типы переменных a и b как any, что может привести к неожиданным ошибкам во время исполнения. Включив noImplicitAny, TypeScript потребует явного указания типов для всех параметров и переменных.

function add(a: number, b: number): number {
  return a + b;
}

noImplicitThis

Включение опции noImplicitThis позволяет компилятору TypeScript проверять контекст выполнения функций. В некоторых случаях в JavaScript this может быть неявно привязан к объекту, что делает код подверженным ошибкам.

function getName() {
  return this.name;
}

В строгом режиме TypeScript будет генерировать ошибку, если контекст this не был явно указан. Чтобы избежать ошибок, можно использовать стрелочные функции или явно указать тип контекста.

const obj = {
  name: "John",
  getName: function() {
    return this.name;
  }
};

strictNullChecks

Проверка на null и undefined — одна из самых важных частей строгого режима. Когда активирована опция strictNullChecks, TypeScript больше не считает null и undefined совместимыми с другими типами, такими как number, string или boolean.

let name: string = null;  // Ошибка при strictNullChecks

Без строгих проверок на null и undefined в обычном режиме TypeScript бы не генерировал ошибку, и переменная name могла бы быть присвоена значению null. Включив strictNullChecks, TypeScript гарантирует, что значения переменных строго соответствуют их типам.

let name: string | null = null;  // Это теперь допустимо

strictFunctionTypes

Эта опция проверяет совместимость типов функций. Без строгих проверок TypeScript может неявно привести типы аргументов и возвращаемых значений, что может привести к ошибкам, особенно в случаях передачи функций как параметров.

let fn: (x: number) => void;
let fn2: (x: string) => void = fn;  // Ошибка при strictFunctionTypes

При включении strictFunctionTypes компилятор требует более строгой проверки типов функций, что помогает избежать ошибок при передаче функций с несоответствующими типами параметров.

strictBindCallApply

Эта опция работает в связке с функциями bind, call и apply. Включение этой проверки делает типы этих методов более строгими и предотвращает ошибки при их использовании.

const obj = { name: "Alice" };
const greet = function(this: { name: string }) {
  return `Hello, ${this.name}`;
};

const greetPerson = greet.bind(obj);
greetPerson();  // Работает корректно

Когда включена проверка strictBindCallApply, TypeScript будет следить за правильной типизацией контекста для этих методов.

esModuleInterop

Опция esModuleInterop позволяет корректно импортировать модули, которые используют CommonJS, в проектах, ориентированных на ES6-модули. Она включается автоматически при активации строгого режима и решает проблему несовместимости между различными форматами модулей.

import * as fs from 'fs';

Включение esModuleInterop упрощает работу с внешними библиотеками, которые используют разные способы экспорта, и предотвращает ошибки при их импорте в TypeScript.

Преимущества и недостатки strict mode

Преимущества:

  • Раннее обнаружение ошибок. За счет более строгой типизации ошибки, которые могли бы быть обнаружены только во время выполнения, становятся видимыми на этапе компиляции.
  • Улучшенная поддержка кода. Код становится более предсказуемым и легко сопровождаемым, так как все типы строго определены.
  • Устранение скрытых багов. TypeScript помогает предотвратить многие проблемы, которые возникали бы в JavaScript из-за неявной типизации и некорректной работы с типами.

Недостатки:

  • Усложнение кода. Для новичков строгая типизация может быть сложной для восприятия, особенно если они не привыкли к явному указанию типов в JavaScript.
  • Потенциальное увеличение объема работы. Включение строгого режима требует дополнительных усилий по исправлению ошибок типизации, что может увеличивать время разработки, особенно в больших проектах.

Заключение

Strict mode в TypeScript — это мощный инструмент для повышения качества кода, который помогает разработчикам работать с более строгими типами и предотвращать ошибки на раннем этапе. Включение этой опции требует дополнительного внимания к типам, но это компенсируется снижением числа ошибок в процессе выполнения и улучшением поддержки кода.