Теория типов

Теория типов

  • 8 июля
  • читать 15 мин
Владимир Шайтан
Владимир Шайтан Senior Full Stack Developer в UKEESS Software House, Преподаватель Компьютерной школы Hillel.

Все мы когда-то начинали, кто-то начинает сейчас. Для нас всех в начале есть одна непонятная штука, какой бы язык программирования мы не учили — типы данных. О них сегодня и поговорим.

Популярность TypeScript растёт, а с ней и актуальность из-за серьезной типизации TypeScript. Благодаря своему опыту, я с теорией типов на "ты". Потому хочу помочь понять и вам. Поехали.

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

И тут мы подошли к вопросу: а как же мы пишем код на JavaScript? Всё просто. Мы, не задумываясь, пишем код по типам, мы мыслим по типам. Объясняю: это будет список с числами или индексами, или список продуктов поэтому я назову его что-то типа array/indexList и т. д., или это будет переменная, где будет лежать предложение с обращением, которое будет генерироваться в зависимости от того, что введёт пользователь.

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

Вам может показаться, что вы готовы к строгой типизации, если вы просто выдадите своим переменным какие-то типы. Но не все так просто. В общем, TypeScript имеет все типы данных, которые имеет JavaScript, и еще немного. Эти типы — всем известные примитивные number, string, boolean, null, undefined, symbol, и bigint. А также:

  • массивы;
  • tuples, которые называют "кортежи" — массивы, которые имеют фиксированное количество элементов;
  • enums (перечни или вычисления) — не дополнение к JavaScript, а именно возможность TypeScript. Этот тип позволяет разработчику определить список или набор именуемых констант. Имеет такой вид:
enum Direction {
 Up = 1,
 Down,
 Left,
 Right,
}
  • any — тип данных, который нужно использовать тогда, когда тип данных переменной неизвестен на момент написания кода, а станет известен при компиляции;
  • unknown — тип, похожий на any, но более безопасный.

Суть в том, что вы тоже можете записать туда любое значение позже, но без приведения к какому-то конкретному типу вы ничего не можете сделать с этими данными.

let value: unknown; 
value = 42;
value = "hello";
value = true;

Ограничения выглядят следующим образом:

let value: unknown = "hello";
console.log(value.length); // Помилка: об'єкт типу 'unknown' не має властивості 'length'
  • void — используется для ничего не возвращающих функций;
  • never — тип, используемый для функций, которые возвращают ошибки или зацикливаются.

Также существуют комплексные типы данных:

  • object;
  • interfaces — используются для определения структуры объёктов. Интерфейс определяет форму объекта, включая имена свойств и типы их значений.

Важно отметить, что интерфейсы не имеют реализации, они только описывают структуру.

Union types или объединенные типы:

let value: number | string;
value = 42;    // Валідно
value = "Hello";  // Валідно

Intersection types или пересечение типов:

interface A {
  propA: string;
}
interface B {
  propB: number;
}
let ab: A & B = { propA: "Hello", propB: 42 };

И мы перешли к дженерикам.

Дженерики (Generics) позволяют создавать компоненты, которые могут работать с разными типами данных, сохраняя при этом информацию о тех же типах. Чаще используются для создания повторно используемых компонентов, таких как функции, классы, интерфейсы или типы, которые могут работать с различными типами данных без потери типобезопасности.

Если мы говорим о дженерик-функции, то будет выглядеть примерно так:

function identity<T>(arg: T): T {
  return arg;
}

let output1 = identity<string>("Hello"); // output1 має тип string
let output2 = identity<number>(42);      // output2 має тип number

Дженерик-интерфейсы выглядят так:

interface Pair<T, U> {
  first: T;
  second: U;
}

let pair: Pair<string, number> = {
  first: "hello",
  second: 42
};

Если кратко, то дженерики являются очень важной частью языка и используются для обеспечения безопасности типов (той же типобезопасности), предсказуемости вашего кода, что само по себе очень упрощает работу.

Хотя TypeScript и является строго типизированным языком, есть операторы типов, которые помогают работать с ними более гибко и динамично. Есть некоторые операторы типов, которые уже знакомы нам с JavaScript, такие как:

  • typeof;
  • instanceof.

На них мы останавливаться не будем, а перейдём дальше, к операторам типов, имеющих прямое отношение исключительно к TypeScript: typeof в контексте типов (неожиданно, правда?)

Это означает, что TypeScript позволяет расширить привычные нам возможности typeof следующим образом:

let s = "hello";
let n: typeof s; // тип 'n' тепер є 'string'

Выглядит просто, на практике удобно.

keyof — возвращает объединение ключей объекта. Звучит сложно, объясняю:

interface Person {
  name: string;
  age: number;
}
type PersonKeys = keyof Person; // 'name' | 'age'

in в контексте условных типов:

type Keys = 'a' | 'b' | 'c';
type Obj = { [K in Keys]: string };

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

Начиная свой путь в TypeScript, вы заметите, как он помогает избегать многих ошибок в JavaScript. Вы начнёте писать код, который будет легче читать, тестировать и поддерживать. Исследуйте примитивные типы, углубляйтесь в дженерики, экспериментируйте с интерфейсами и операторами типов — всё это сделает вас более опытным и уверенным разработчиком.

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

Уметь разобраться в чём-то — самый главный, самый дорогой навык абсолютно для всех и всегда. Именно это продаст вас, как работника, именно это будет вашим рекомендательным письмом для следующего работодателя. Развивайте, тренируйте это и всё у вас получится.

Мы скоро встретимся с вами на обсуждении новых интересных тем и вещей. До встречи!

Рекомендуем курсы по теме