Typescript: Псевдонимы типов (Type Aliases)
Представим программу, в которой есть объект пользователя. Этот объект используется повсеместно. В такой ситуации описание типа этого объекта будет повторяться в каждом определении функции:
function doSomething(user: { firstName: string; pointsCount: number }) {}
function doSomethingElse(user: { firstName: string; pointsCount: number }) {}
function doSomethingAnother(user: { firstName: string; pointsCount: number }) {}Во-первых, здесь много дублирования. Во-вторых, значительно усложняется изменение структуры, потому что придется руками править все места, где встречается это определение. В этом уроке разберем, как избежать таких проблем.
Задаем псевдоним типа
Чтобы не делать одну и ту же работу, да еще и руками, TypeScript позволяет задавать псевдоним (alias) для составных типов. Так мы не будем повторяться:
type User = {
firstName: string
pointsCount: number
}Теперь можно провести замену во всех функциях:
function doSomething(user: User) {
// ...
}Псевдоним — это не создание нового типа данных. Это способ сокращенно записать определение типа. Поэтому следующие примеры будут работать без проблем:
const user = {
firstName: "Mike",
pointsCount: 1000,
};
// Оба вызова работают
doSomething(user);
doSomething({ firstName: "Bob", pointsCount: 1800 });При этом разработчики на TypeScript говорят «создаем тип», а не «создаем псевдоним типа». Поэтому в этом курсе мы будем придерживаться общепринятого формата.
Типы можно задавать для любых типов данных. Например, для простых:
type SomeType = string;А также для составных:
// union тип из трех возможных значений
type SomeType = string | number | null;
// Функция
type Countable = (coll: number[]) => number;Объекты и функции
Описание типа функции вне объекта и внутри отличается. Когда функция записывается самостоятельно, используется формат стрелочной функции:
type Countable = (coll: number[]) => number;Внутри типа, который описывает объект, формат меняется на используемый для обычных свойств:
type User = {
firstName: string;
pointsCount: number;
count(coll: number[]): number;
};Но это не касается колбеков, которые могут быть использованы внутри:
type User = {
firstName: string;
pointsCount: number;
// Типы взяты для примера
count(coll: (v: string) => string): number;
};В этом уроке мы научились использовать псевдонимы типов. Также мы узнали, как задавать псевдоним для составных типов.
Задание
Реализуйте функцию getOlderUser(), которая принимает на вход двух пользователей и возвращает того, который старше. Если пользователи являются ровесниками, то возвращается null:
const user1 = { name: "Petr", age: 8 };Определите для пользователя псевдоним, чтобы не дублировать определение его типа в параметрах функции.
Typescript: Псевдонимы типов (Type Aliases)
Представим программу, в которой есть объект пользователя. Этот объект используется повсеместно. В такой ситуации описание типа этого объекта будет повторяться в каждом определении функции:
function doSomething(user: { firstName: string; pointsCount: number }) {}
function doSomethingElse(user: { firstName: string; pointsCount: number }) {}
function doSomethingAnother(user: { firstName: string; pointsCount: number }) {}Во-первых, здесь много дублирования. Во-вторых, значительно усложняется изменение структуры, потому что придется руками править все места, где встречается это определение. В этом уроке разберем, как избежать таких проблем.
Задаем псевдоним типа
Чтобы не делать одну и ту же работу, да еще и руками, TypeScript позволяет задавать псевдоним (alias) для составных типов. Так мы не будем повторяться:
type User = {
firstName: string
pointsCount: number
}Теперь можно провести замену во всех функциях:
function doSomething(user: User) {
// ...
}Псевдоним — это не создание нового типа данных. Это способ сокращенно записать определение типа. Поэтому следующие примеры будут работать без проблем:
const user = {
firstName: "Mike",
pointsCount: 1000,
};
// Оба вызова работают
doSomething(user);
doSomething({ firstName: "Bob", pointsCount: 1800 });При этом разработчики на TypeScript говорят «создаем тип», а не «создаем псевдоним типа». Поэтому в этом курсе мы будем придерживаться общепринятого формата.
Типы можно задавать для любых типов данных. Например, для простых:
type SomeType = string;А также для составных:
// union тип из трех возможных значений
type SomeType = string | number | null;
// Функция
type Countable = (coll: number[]) => number;Объекты и функции
Описание типа функции вне объекта и внутри отличается. Когда функция записывается самостоятельно, используется формат стрелочной функции:
type Countable = (coll: number[]) => number;Внутри типа, который описывает объект, формат меняется на используемый для обычных свойств:
type User = {
firstName: string;
pointsCount: number;
count(coll: number[]): number;
};Но это не касается колбеков, которые могут быть использованы внутри:
type User = {
firstName: string;
pointsCount: number;
// Типы взяты для примера
count(coll: (v: string) => string): number;
};В этом уроке мы научились использовать псевдонимы типов. Также мы узнали, как задавать псевдоним для составных типов.
Задание
Реализуйте функцию getOlderUser(), которая принимает на вход двух пользователей и возвращает того, который старше. Если пользователи являются ровесниками, то возвращается null:
const user1 = { name: "Petr", age: 8 };Определите для пользователя псевдоним, чтобы не дублировать определение его типа в параметрах функции.
Ваше упражнение проверяется по этим тестам
import { expect, expectTypeOf, test } from "vitest";
import getOlderUser, { type User } from "./index";
test("function", () => {
const user1 = {
name: "sem",
age: 3,
};
const user2 = {
name: "inna",
age: 5,
};
const user3 = {
name: "mika",
age: 5,
};
expect(getOlderUser(user1, user2)).toEqual(user2);
expect(getOlderUser(user2, user1)).toEqual(user2);
expect(getOlderUser(user2, user3)).toBeNull();
expectTypeOf(getOlderUser).returns.toExtend<User | null>();
});Решение учителя откроется через:
20:00
