В TypeScript 2.0 в язык был добавлен модификатор readonly.
Свойства, помеченные readonly, могут быть присвоены только во время инициализации или из конструктора того же класса. Все остальные назначения запрещены.
// type definitions interface Person { readonly name: string; readonly age: number; }; // or type Person = { readonly name: string; readonly age: number; }; // Usage: const person: Person = { name: Mike, age: 23 };
Теперь, поскольку свойства name и age объявлены как readonly, значение любого из них не может быть переназначено во время компиляции:
person.name="Kate" // not allowed person.age = 33 // not allowed
Это дает разработчику дополнительный уровень безопасности, поскольку компилятор проверяет непреднамеренное присвоение свойств во время разработки. А это уменьшает количество потенциальных ошибок во время выполнения.
Также стоит прямо заявить, что модификатор readonly является частью системы типов TypeScript, и что после компиляции кода Typescript в JavaScript модификаторы readonly удаляются из кода. Поэтому не существует защиты от переназначения свойств во время выполнения.
Защита типов - это техника, используемая для получения типа переменной внутри условного блока.
Защитники типов обычно реализуются в виде функций.
Защитники типов позволяют разработчикам определить правильные методы, прототипы и свойства значения.
TypeScript использует некоторые встроенные операторы JavaScript, такие как typeof, instanceof и оператор in, которые используются для определения того, содержит ли объект свойство.
const isString = (value: unknown): value is string => typeof value === "string"; // .... if (isString(value)) { console.info(value.toUpperCase()); }
Оператор typeof может определять следующие типы, распознаваемые JavaScript; boolean, string, bigint, symbol, undefined, function, number.
interface Vehicle { manufacturer: VehicleManufacturer; model: VehicleModel; } interface Animal { name: string; species: AnimalSpecies; } const getUniqueID = (entity: Vehicle | Animal) => { if ("manufacturer" in entity) { return entity.manufacturer; } if ("species" in entity) { return `${entity.name} - ${entity.species}`; } ... }
Оператор in проверяет, обладает ли объект определенным свойством. Он также обычно реализуется как функция и возвращает булеву величину.
Он очень полезен для сужения свойств, как в примере выше.
Тип объединения описывает значение, которое может быть одним из нескольких типов. Мы используем вертикальную полосу (|) для разделения каждого типа, поэтому число | строка | булево - это тип значения, которое может быть числом, строкой или булевым числом.
type Status="active" | "inactive" | "pending"; const setStatus = (status: Status) => { // ... } setStatus("active"); setStatus("pending"); setStatus("invalid"); // Error: Argument of type '"invalid"' is not assignable to parameter of type 'Status'.
Welcome to DeepL Write!
// type guards const isString = (value: unknown): value is string => { return typeof value === "string"; } const isNumber = (value: unknown): value is number => { return typeof value === "number"; } // simple union type type ID="string" | "number"; const getNameFromID = (id: ID) => { if (isString(id)) { // logic that deals with id: string } if (isNumber(id)) { // logic that deals with id: number } // default return, or error handling logic } getNameFromID("23"); getNameFromID(45);
interface Bird { weight: number; canFly: boolean; } interface Dog { age: number; canFly: boolean; } const canAnimalFly = (animal: Bird | Dog) => animal.canFly; // even better for readability and scalability purposes type Animal = Bird | Dog; const canAnimalFly = (animal: Animal) => animal.canFly;
Click on a word to see suggestions or rewrite the whole sentence.
Но что, если мы хотим получить доступ к свойству weight для объекта bird: Объект "Птица", или свойство "Возраст" у собаки: Объект Dog?
type Animal = Bird | Dog; const bird: Animal = bird.age // TS error
Компилятор TypeScript пожаловался бы и выдал ошибку.
Поскольку TS является структурно типизированным языком, он разрешает доступ только к свойствам, определенным в обоих интерфейсах.
Техника защиты типов, которая помогает нам удовлетворить компилятор TS:
interface Bird { weight: number; canFly: boolean; } interface Dog { age: number; canFly: boolean; } type Animal = Bird | Dog; const getAnimalAge = (animal: Animal) => { if ("age" in animal) { return animal.age; } return undefined; } const getAnimalWeight = (animal: Animal) => { if ("weight" in animal) { return animal.weight; } return undefined; }
Теперь представьте, что мы добавили больше общих свойств в интерфейс Bird или Dog. Или что если мы удалим некоторые общие свойства из обоих интерфейсов, которые также используются внутри защит типов? Например, canFly.Итак, вот модифицированный пример вышеприведенного кода, использующий метод
Более "пуленепробиваемая" реализация, которая будет работать для более сложных типов с большим количеством перекрытий и глубиной, будет заключаться в присоединении дополнительного свойства идентификатора к обоим интерфейсам, которое мы могли бы также использовать для определения типа параметра во время выполнения.
Например:
interface Bird { weight: number; canFly: boolean; ANIMAL_TYPE: "BIRD"; } interface Dog { age: number; canFly: boolean; ANIMAL_TYPE: "DOG"; } type Animal = Bird | Dog; const getAnimalAge = (animal: Animal) => { if (animal.ANIMAL_TYPE === "DOG") { return animal.age; } return undefined; } const getAnimalWeight = (animal: Animal) => { if (animal.ANIMAL_TYPE === "BIRD") { return animal.weight; } return undefined; }
свойство нашим JS-объектам (которые не имеют никакой бизнес-ценности). А это увеличивает потребление памяти - но, вероятно, не намного.
Спасибо, что дочитали эту статью до конца.
Надеюсь, сегодня вы узнали что-то новое. А если нет, то, возможно, это помогло вам укрепить некоторые концепции.Недостатком этого подхода является то, что мы присоединяем дополнительное свойство к нашему JS-объекту.
.org/docs/handbook/typescript-in-5-minutes.html
2) https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html В будущем я буду публиковать больше подобных материалов, так что следите за новостями :)
Ресурсы:
1) https://www.typescriptlang
20.08.2023 18:21
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".
20.08.2023 17:46
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
19.08.2023 18:39
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.
19.08.2023 17:22
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!
18.08.2023 20:33
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.
14.08.2023 14:49
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.