В чем разница между типами String и string в TypeScript?
Краткий ответ
Используйте string (с маленькой буквы) всегда, когда объявляете тип переменной. String (с большой буквы) — это встроенный JavaScript-конструктор (класс), который почти никогда не нужен для аннотации типов в TypeScript.
Подробное объяснение
В TypeScript есть два совершенно разных понятия:
string— это примитивный тип, обозначающий простую строку. Это литералы, переменные и результаты операций.String— это ссылочный тип (объект-обёртка), который создаётся при вызовеnew String("...").
Проблема в том, что JavaScript автоматически преобразует примитивные строки в объекты String при вызове методов (например, "hello".toUpperCase()), поэтому новички не замечают разницы. Но в TypeScript эта разница критична.
Пример, показывающий разницу
// Примитивный тип string
let primitiveStr: string = "Hello";
console.log(typeof primitiveStr); // "string"
// Объектный тип String (через конструктор)
let objectStr: String = new String("Hello");
console.log(typeof objectStr); // "object" — это объект, а не строка!
// Сравнение
console.log(primitiveStr === objectStr); // false! Разные типы
console.log(primitiveStr == objectStr); // true (нестрогое сравнение преобразует объект в примитив)
// Проверка с помощью typeof
if (typeof primitiveStr === "string") { /* true */ }
if (typeof objectStr === "string") { /* false — это object */ }
Почему не стоит использовать String как тип?
- Проблемы с присваиванием: если функция ожидает
string, а вы передаётеString, TypeScript выдаст ошибку (если включён strict mode). - Ложное чувство безопасности:
Stringможет бытьnullилиundefined, аstring— нет (если не указано иное). - Производительность: объекты
Stringмедленнее и занимают больше памяти.
Когда String может быть полезен?
Практически никогда для типов. Единственный легитимный случай — если вы пишете код, который явно работает с объектами-обёртками (например, расширяете прототип String). Но это считается плохой практикой в современном JavaScript.
Правило для новичков
// ✅ Правильно
let name: string = "John";
function greet(msg: string): void { ... }
// ❌ Неправильно (но технически работает)
let name: String = "John";
function greet(msg: String): void { ... }
Запомните: всегда используйте string для аннотации типов. String оставьте только для вызова статических методов, например String.fromCharCode().
Дополнение: как TypeScript обрабатывает несоответствие
Хотя на первый взгляд string и String взаимозаменяемы, TypeScript имеет встроенную защиту. Если вы включите в tsconfig.json опцию "strict": true (а это рекомендуется), то компилятор начнёт различать эти типы в некоторых сценариях.
// В strict mode это вызовет ошибку
function processString(input: string) {
console.log(input.length);
}
const objStr: String = new String("test");
processString(objStr); // ❌ Error: Argument of type 'String' is not assignable to parameter of type 'string'
Почему это важно для проверки типов?
Представьте, что вы пишете библиотеку и ожидаете string, а пользователь передаёт String. Если вы попытаетесь использовать typeof для проверки, то получите "object", а не "string". Это может привести к багам в runtime.
Практический совет
Если вы видите в чужом коде String как тип — скорее всего, это ошибка или код, написанный начинающим разработчиком. Исправляйте на string. Исключение — если вы работаете с очень старым JavaScript-кодом, где используются объекты-обёртки, но в современном TypeScript это не нужно.
Запомните: примитивные типы в TypeScript пишутся с маленькой буквы: string, number, boolean, symbol, bigint. С большой буквы — это конструкторы, которые не предназначены для аннотации типов.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги