Приведение типов с помощью TypeScript: руководство

Эта статья изначально была написана в блоге DeadSimpleChat: Приведение типов с помощью TypeScript: руководство.

Приведение типов — важный метод и технология, особенно в TypeScript.

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

Вот некоторые из причин, почему приведение типов важно в TypeScript.

  1. Работа со сложными типами
  2. Работа с устаревшими библиотеками JavaScript
  3. Работа с неизвестными типами.
  4. Умение выполнять простые манипуляции с типами
  5. Создание функций Type Guard

1. Работа со сложными типами

Чтобы понять предполагаемый тип данных, важно преобразовать один тип в другой. Это справедливо при работе с вложенными типами данных или сложными типами данных.

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

2. Работа с устаревшими библиотеками Javascript

Если вы хотите обеспечить безопасность типов и предотвратить ошибки во время выполнения в устаревших библиотеках JavaScript, которые не были написаны на TypeScript.

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

3. Работа с неизвестными типами

При анализе данных JSON или работе с внешним API вы можете столкнуться с неизвестными типами.

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

4. Умение выполнять простые манипуляции с текстами.

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

5. Создание функций защиты типа

С помощью TypeScript вы можете создавать собственные функции Type Guard с помощью оператора isType. Приведение типов помогает определить, относится ли данное значение к ожидаемому типу. Затем, если оно того типа, который нам нужен, мы можем использовать это значение в следующем процессе, или, если утверждение не удалось, мы можем подумать, что делать со значением.

Основы приведения типов

Явное и неявное приведение типов

Что такое неявное приведение типов?

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

Средство проверки типов TypeScripts автоматически определяет предполагаемый тип данного значения, и разработчик не требует ручного вмешательства.

Давайте рассмотрим пример

let stringValue: string = '42';
let numberValue: number = stringValue as unknown as number; // Double Casting is done here causing implicit conversion

Что такое явное приведение типов?

Явное приведение типов — это когда разработчик намеренно выполняет преобразование типа, поэтому разработчик явно предоставляет тип.

TypeScript предлагает 2 способа, которыми разработчик может это сделать.

  • Использование угловых кронштейнов
  • Использование ключевого слова as

Угловые скобки и ключевое слово as

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

давайте посмотрим на пример

let someValue: any = 'Some String Value';
let strLength: number = (<string>someValue).length;

Этот метод является более старым способом приведения типов в TypeScript. Давайте посмотрим на еще один современный вариант Type Cast:

Использование ключевого слова as

Ключевое слово as было добавлено в машинописный текст как способ приведения типов. Этот метод прост в использовании и более читабелен.

Метод старых угловых скобок также может конфликтовать с JSX, поэтому ключевое слово as является предпочтительным способом приведения типов в TypeScript.

Давайте рассмотрим пример

let someValue: any = 'This is a random string';
let strLength: number = (someValue as string).length;

Нет. Независимо от того, какой метод вы используете для приведения типов, TypeScript гарантирует, что приведение допустимо и разрешено.

TypeScript всегда будет стремиться обеспечить безопасность типов.

Неправильное использование приведения типов может привести к ошибкам.

Примеры

Специальный тип защиты

Что такое тип гвардии?

Тип Guards — это функции. Эти функции сужают область действия данного значения до определенного типа.

Это позволяет машинописному тексту различать типы.

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

давайте посмотрим на пример

class Individual {
  constructor(public name: string, public age: number) {}
}

class Car {
  constructor(public make: string, public model: string) {}
}

function isIndividual(obj: any): obj is Individual {
  return obj instanceof Individual;
}

const someItem = new Individual('Jo', 23);

if (isIndividual(someItem)) {
  // TypeScript will recognw someItem as Individual within this scope
  console.log(someItem.name);
} else {
  console.log('This Object is not an Individual object');

Кастинг в функциональном программировании

Что такое функциональное программирование?

Функциональное программирование означает наличие функциональных принципов, таких как неизменность, функции высшего порядка и т. д.

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

Давайте займемся приведением типов с помощью функции map.

type Circle = {
  kind: 'circle';
  radius: number;
};

type Square = {
  kind: 'square';
  sideLength: number;
};

type Shape = Circle | Square;

const shapes: Shape[] = [
  { kind: 'circle', radius: 5 },
  { kind: 'square', sideLength: 10 },
];

// Writing a function to calculate a shape's area depending in the what kind it is

function area(shape: Shape): number {
  if (shape.kind === 'circle') {
    return Math.PI * shape.radius ** 2;
  } else {
    return shape.sideLength ** 2;
  }
}

const areas: number[] = shapes.map(shape => area(shape));

Мы используем условные и сопоставленные типы для выполнения расширенного приведения типов. Мы также обеспечиваем безопасность типов при выполнении расширенного приведения типов.

Давайте узнаем больше о передовых методах и технологиях в следующем разделе.

Передовые методы

Есть 2 техники, которые мы собираемся изучить сегодня. 1. Метаданные типов отражения и времени выполнения. 2. использование условных и отображаемых типов

Оба эти типа подробно объяснены ниже с примерами.

Метаданные отражения и времени выполнения

TypeScritpt по умолчанию обеспечивает проверку типов во время компиляции. Если вам нужна дополнительная динамическая проверка типов во время выполнения, вы можете использовать декораторы и библиотеки, такие как reflect-metadata Reflection включает проверку структуры данных типа во время выполнения.

давайте рассмотрим пример с использованием reflect-matadata

import 'reflect-metadata';

class User {
  constructor(public name: string, public age: number) {}
}

function logType(target: Object, key: string) {
  const targetType = Reflect.getMetadata('design:type', target, key);
  console.log(`${key} has type ${targetType.name}`);
}

class MyClass {
  @logType
  public user: User;
}

const instance = new MyClass();

Использование условных типов и сопоставленных типов для расширенного приведения

Условные типы

определение типов на основе определенного условия известно как условные типы в TypeScript.

Эта статья предоставлена ​​вам DeadSimpleChat, Chat API и SDK для вашего веб-сайта и приложения.

Типы условий имеют особый синтаксис, т.е.

T extends U ? X : Y

Это означает, что если T расширяет вас, то тип — X, в противном случае — Y.

type IsString<T> = T extends string ? 'true' : 'false';

type StringCheck = IsString<string>; // 'true'
type NumberCheck = IsString<number>; // 'false'

Сопоставленные типы

Вы можете перебирать существующие типы и изменять их свойства по мере необходимости для создания новых типов.

Например: мы можем создавать разные версии одного и того же типа, доступные только для чтения.

type Readonly<T> = {
  readonly [K in keyof T]: T[K];
};

interface Person {
  name: string;
  age: number;
}

type ReadonlyPerson = Readonly<Person>;

const person: ReadonlyPerson = {
  name: 'Alice',
  age: 30,
};

// The following code would throw a compile time error
// person.age = 31;

Используя условные и сопоставленные типы, мы можем выполнять сложное приведение типов с помощью TypeScript.

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

Примеры: примеры из реальной жизни и варианты использования для лучшего понимания.

1. Безопасный анализ JSON:

Использование встроенной функции JSON.parse JavaScript

В этом примере мы будем использовать приведение типов для проверки типа анализа объекта с помощью функции JSON.parse.

Встроенная функция JavaScript JSON.parse может преобразовать строку JSON в объект JavaScript.

Однако TypeScript не знает, какой тип объекта анализируется функцией JSON.parse.

Мы будем использовать приведение типов, чтобы предоставить правильную информацию о типе.

const individualInformation = '{"name": "John Doe", "age": 23}';
const parsedJSON = JSON.parse(individualInformation);

Функция приведения пользовательского типа

Далее мы создадим специальную защитную функцию для проверки структуры JSON, анализируемой с помощью функции JSON.parse.

interface Individual {
  name: string;
  age: number;
}

function isIndividual(obj: any): obj is Individual {
  return (
    typeof obj === 'object' &&
    obj !== null &&
    typeof obj.name === 'string' &&
    typeof obj.age === 'number'
  );
}

Теперь мы создали пользовательскую функцию, которую можем использовать для подтверждения типа JSON, проанализированного функцией JSON.parse.

Утверждение типа анализируемого JSON

Давайте теперь утверждаем, что JSON, проанализированный объектом JSON.parse, имеет определенный тип или нет.

const IndividualInformation = '{"name": "Joe", "age": 23}';
const parsedJSON = JSON.parse(IndividualInformation);

if (isIndividual(parsedJSON)) {
  
  const individual: Individual = parsedJSON;
  console.log(`Hi, I am ${individual.name} and I am ${individual.age} years old.`);
} else {
  console.error('The JSON string does not represent a Individual object');
}

В приведенном выше примере мы используем специальную защитную функцию isIndividual, чтобы проверить, что проанализированный JSON имеет тип «Индивидуальный».

Объект Individual здесь служит неявным приведением типов и обеспечивает безопасность и целостность кода.

2. Преобразование ответов API

В этом примере мы будем преобразовывать ответы JSON API с помощью служебной функции и использовать методы манипулирования типами для достижения безопасности типов.

В качестве примера API мы будем использовать веб-сайты-заполнители JSON todos api.

https://jsonplaceholder.typicode.com/

Эта конечная точка возвращает следующие данные:

[
  {
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  },
 ...
]

Создание функции для получения данных из API

Мы собираемся создать функцию, которая будет получать данные из конечной точки todos.

async function fetchTodos() {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos');
  const todos = await response.json();
  return todos;
}

Создание служебной функции для обработки ответов JSON

Мы знаем, что не гарантируется, что ответы JSON, которые мы получаем от конечной точки, не всегда будут в той структуре или формате, которые мы от них требуем.

Мы можем создать служебную функцию, которая проверяет и сужает тип ответа, используя функцию проверки типа.

interface Todo {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

function isTodoArray(obj: any): obj is Todo[] {
  return Array.isArray(obj) && obj.every(isTodo);
}

function isTodo(obj: any): obj is Todo {
  return (
    typeof obj === 'object' &&
    obj !== null &&
    typeof obj.userId === 'number' &&
    typeof obj.id === 'number' &&
    typeof obj.title === 'string' &&
    typeof obj.completed === 'boolean'
  );
}

Обеспечьте безопасность типов с помощью расширенных манипуляций с типами.

Мы собираемся обрабатывать ответы JSON, используя служебную функцию.

async function main() {
  const fetchedTodos = await fetchTodos();

  if (isTodoArray(fetchedTodos)) {
    // typescript will recognise the 
    const todos: Todo[] = fetchedTodos;

    // Advanced type manipulation: Extract only completed todos
    const completedTodos = todos.filter(todo => todo.completed);

    console.log('Completed Todos:', completedTodos);
  } else {
    console.error('API response does not match expected structure');
  }
}

main().catch(error => {
  console.error('An error occurred:', error);
});

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

Потенциальные ловушки и распространенные ошибки

Нужен Chat API для вашего сайта или приложения

DeadSimpleChat — поставщик API чата.

  • Добавьте масштабируемый чат в свое приложение за считанные минуты
  • 10 миллионов одновременных онлайн-пользователей
  • 99,999% времени безотказной работы
  • Функции модерации
  • 1–1 Чат
  • Групповой чат
  • Полностью настраиваемый
  • API чата и SDK
  • Готовый чат

Заключение

В этой статье мы узнали о приведении типов в TypeScript.

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

Мы рассмотрели современные технологии и продемонстрировали примеры из реальной жизни с использованием ответов JSON и API.

Надеюсь, статья вам понравилась и спасибо, что прочитали.