TypeScript - Утилитарные типы

Здравствуйте, будущие кодинговые маги! Сегодня мы отправимся в увлекательное путешествие по магическому миру утилитарных типов TypeScript. Не волнуйтесь, если вы новички в программировании; я буду вашим дружественным проводником, и мы вместе исследуем эти концепции, шаг за шагом. Так что возьмите свои виртуальные палочки (клавиатуры), и lets dive in!

TypeScript - Utility Types

Что такое утилитарные типы?

Прежде чем мы начнем, давайте поймем, что такое утилитарные типы. Представьте себе ящик с различными инструментами. Каждый инструмент помогает вам выполнять определенную задачу более эффективно. Именно такими и являются утилитарные типы в TypeScript - это预制 инструменты, которые помогают нам манипулировать и преобразовывать типы легко.

Теперь давайте рассмотрим каждый из этих магических инструментов по одному!

Тип Partial в TypeScript

Тип Partial resembles a spell that makes all properties in an object optional. It's super useful when you want to create an object where you don't need to specify all properties.

Давайте увидим это в действии:

interface Wizard {
  name: string;
  age: number;
  house: string;
}

function updateWizard(wizard: Wizard, fieldsToUpdate: Partial<Wizard>) {
  return { ...wizard, ...fieldsToUpdate };
}

const harryPotter: Wizard = {
  name: "Harry Potter",
  age: 11,
  house: "Gryffindor"
};

const updatedHarry = updateWizard(harryPotter, { age: 17 });
console.log(updatedHarry);
// Вывод: { name: "Harry Potter", age: 17, house: "Gryffindor" }

В этом примере Partial<Wizard> позволяет нам обновить только возраст Гарри, не указывая все остальные свойства. Это как взмахнуть палочкой и сказать "Partial Revelio!"

Тип Required в TypeScript

Тип Required - это相反ность Partial. Это как casting a spell что делает все свойства в объекте обязательными, даже если ониoriginally были可选.

interface MagicalCreature {
  name: string;
  power?: string;
  age?: number;
}

const dragon: Required<MagicalCreature> = {
  name: "Norwegian Ridgeback",
  power: "Fire Breath",
  age: 2
};

// Это вызвало бы ошибку:
// const unicorn: Required<MagicalCreature> = {
//   name: "Silver Horn"
// };

Здесь, даже though power и age были可选 в исходном интерфейсе, тип Required делает их обязаельными. Это как сказать "Accio all properties!"

Тип Pick в TypeScript

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

interface Potion {
  name: string;
  ingredients: string[];
  brewingTime: number;
  effect: string;
}

type PotionLabel = Pick<Potion, 'name' | 'effect'>;

const polyjuicePotion: PotionLabel = {
  name: "Polyjuice Potion",
  effect: "Transforms the drinker into another person"
};

В этом примере мы создали новый тип PotionLabel, который включает только свойства name и effect из интерфейса Potion. Это идеально для тех случаев, когда вам нужно только несколько конкретных деталей!

Тип Omit в TypeScript

Тип Omit - это相反ность Pick. Он создает новый тип, удаляя конкретные свойства из существующего типа. Представьте себе, что вы используете заклинание Vanishing Spell на некоторых свойствах!

interface SpellBook {
  title: string;
  author: string;
  pages: number;
  secretSpell: string;
}

type PublicSpellBook = Omit<SpellBook, 'secretSpell'>;

const beginnerSpellBook: PublicSpellBook = {
  title: "Standard Book of Spells, Grade 1",
  author: "Miranda Goshawk",
  pages: 250
};

Здесь мы создали тип PublicSpellBook, который включает все свойства SpellBook, кроме secretSpell. Это как сказать "Show me everything but the secret!"

Тип Readonly в TypeScript

Тип Readonly resembles a protection spell on your properties. It makes all properties in a type read-only, preventing accidental modifications.

interface Wand {
  wood: string;
  core: string;
  length: number;
}

const harryWand: Readonly<Wand> = {
  wood: "Holly",
  core: "Phoenix feather",
  length: 11
};

// Это вызвало бы ошибку:
// harryWand.length = 12;

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

Тип ReturnType в TypeScript

Тип ReturnType позволяет извлечь тип返回 значения функции. Это как использовать заклинание Legilimency, чтобы заглянуть в функцию и увидеть, что она возвращает!

function castSpell(spellName: string): { name: string, power: number } {
  // Логика cast заклинания здесь
  return { name: spellName, power: Math.random() * 100 };
}

type SpellResult = ReturnType<typeof castSpell>;

const lumos: SpellResult = {
  name: "Lumos",
  power: 50
};

В этом примере SpellResult выводится как { name: string, power: number }, что является типом返回 значения функции castSpell. Это incredibly полезно при работе с сложными функциями!

Тип Record в TypeScript

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

type HouseCup = Record<string, number>;

const housePoints: HouseCup = {
  "Gryffindor": 472,
  "Hufflepuff": 352,
  "Ravenclaw": 426,
  "Slytherin": 472
};

Здесь HouseCup - это тип, где ключи - это строки (имена домов), а значения - это числа (очки). Это гарантирует, что наш объект очков имеет правильную структуру.

Тип NonNullable в TypeScript

Тип NonNullable resembles a spell to banish null and undefined values. It creates a new type by excluding null and undefined from a given type.

type MagicalItem = string | number | null | undefined;

type DefiniteMagicalItem = NonNullable<MagicalItem>;

const definiteItem: DefiniteMagicalItem = "Invisibility Cloak";
// Это вызвало бы ошибку:
// const nullItem: DefiniteMagicalItem = null;

В этом примере DefiniteMagicalItem - это тип, который может быть строкой или числом, но не null или undefined. Это идеально, когда вы хотите быть уверенными, что работаете с actual значениями!

Шпаргалка по утилитарным типам

Вот quick reference таблица для всех утилитарных типов, которые мы рассмотрели:

Утилитарный тип Описание Пример
Partial Makes all properties in T optional Partial<Wizard>
Required Makes all properties in T required Required<MagicalCreature>
Pick<T, K> Creates a type with only the properties K from T Pick<Potion, 'name' | 'effect'>
Omit<T, K> Creates a type without the properties K from T Omit<SpellBook, 'secretSpell'>
Readonly Makes all properties in T read-only Readonly<Wand>
ReturnType Extracts the return type of a function type T ReturnType<typeof castSpell>
Record<K, T> Creates an object type with keys of type K and values of type T Record<string, number>
NonNullable Creates a type by excluding null and undefined from T NonNullable<MagicalItem>

И вот вы,年轻的巫师们! Теперь вы освоили базовые заклинания утилитарных типов TypeScript. Помните, как и любая магия, эти типы становятся более powerful с практикой. Так что продолжайте экспериментировать, и вскоре вы будете cast этих типов так же легко, как saying "Wingardium Leviosa"!

Credits: Image by storyset