В JavaScript есть типы. Существует 8 типов данных.
Но при этом JS имеет динамическую и неявную типизацию.
🟣Динамическая означает, что тип переменной определяется не при ее объявлении, а во время выполнения программы в момент присваивания значения и может меняться динамически.
let value = 42; // Тип: number
console.log(typeof value); // "number"
value = "текст"; // Тип изменился во время выполнения
console.log(typeof value); // "string"
value = true; // Тип снова изменился
console.log(typeof value); // "boolean"
🟣Неявная говорит о том, что тип выводится автоматически без явного указания.
let x = 'hello world!'
console.log(typeof x); // "string"
В данной строке javascript автоматически определит, что в переменной x лежит строка.
TypeScript также поддерживает неявный вывод типов, который помогает упростить код.
Однако не всегда можно полностью полагаться на него - в некоторых случаях компилятор не сможет однозначно определить тип.
При необходимости в TypeScript можно явно указать тип для переменных, чтобы повысить читаемость и надежность кода:
let x: string = 'hello world!'
🟣TypeScript является надстройкой над JavaScript и добавляет статическую типизацию.
Это означает, что тип переменной определяется на этапе компиляции кода, что позволяет получать мощные подсказки от IDE и выявлять ошибки на этапе написания кода.
То есть код анализируется не запускаясь.
🟣Это круто, но при этом имеет свои ограничения, например, при работе с данными в райнтайме.
Если мы делаем fetch-запрос к бэкенду и ожидаем данные определённого типа - TS вынужден «доверять» разработчикам, потому что не сможет проверить этот тип во время выполнения.
Посмотрим на примере следующего кода. У нас есть тип Mentor и функция fetchMentor, когда получает данные с бекенда по айди ментора.
Но допустим, в какой-то момент, бекенд изменил контракт и данные пришли не те, которые мы ожидали. TypeScript этого не знает, потому что функция fetchMentor обещала, что результат будет типа Mentor.
type Mentor = {
id: string;
name: string;
email: string;
};
async function fetchMentor(id: number): Promise<Mentor> {
const res = await fetch(`/api/mentors/${id}`);
return await res.json(); // ← TypeScript верит, что это тип Mentor
}
const mentor = await fetchMentor(1);
// А с сервера пришло { "id": 1, "fullname": "Frontend Alliance" }
console.log(mentor.name.toUpperCase()); // Упали в рантайме, так как нет поля nameTypeScript проверяет типы только во время компиляции, а не в рантайме.
Тоже самое касается например парсинга localStorage - мы не можем в райтайме проверить, что там в действительности будет.
const x: number = JSON.parse(localStorage.getItem('my-favorite-number') || '');🟣Когда мы видим запись вида:
const x: number
мы думаем, что в переменной x лежит число, но это не до конца верно.
Эта запись означает, что мы верим, что там лежит число, но формально этого может не быть.
На этапе статического анализа мы не можем гарантировать, что после fetch'a и LS'a данные будут определенного типа.
О том как себя обезопасить в рантайме - будет в отдельном посте.
✈️ Telegram | 🎓 Менторство | 📹 YouTube | 👩💻 Roadmap