JS Tower
JavaScript & TypeScriptПодготовка к собеседованию

Задачи на TypeScript

Типичные задачи на типизацию

Цель урока

Разбор задач на TypeScript, которые дают на собеседованиях.


Реализуй Partial

type MyPartial<T> = {
  [K in keyof T]?: T[K];
};

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

type PartialUser = MyPartial<User>;
// { name?: string; age?: number; }
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
OK

Реализуй Required

type MyRequired<T> = {
  [K in keyof T]-?: T[K];
};

Реализуй Readonly

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

Реализуй Pick

type MyPick<T, K extends keyof T> = {
  [P in K]: T[P];
};

interface User {
  id: number;
  name: string;
  email: string;
}

type UserName = MyPick<User, "name">;
// { name: string; }
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
OK

Реализуй Omit

type MyOmit<T, K extends keyof T> = {
  [P in Exclude<keyof T, K>]: T[P];
};

// Или через Pick
type MyOmit2<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

Реализуй Exclude

type MyExclude<T, U> = T extends U ? never : T;

type Result = MyExclude<"a" | "b" | "c", "a">;
// "b" | "c"
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
b c

Реализуй ReturnType

type MyReturnType<T extends (...args: any[]) => any> = 
  T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { name: "Иван", age: 25 };
}

type User = MyReturnType<typeof getUser>;
// { name: string; age: number; }

Реализуй Parameters

type MyParameters<T extends (...args: any[]) => any> = 
  T extends (...args: infer P) => any ? P : never;

function greet(name: string, age: number) {}

type Params = MyParameters<typeof greet>;
// [string, number]

DeepReadonly

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object
    ? T[K] extends Function
      ? T[K]
      : DeepReadonly<T[K]>
    : T[K];
};

interface User {
  name: string;
  address: {
    city: string;
  };
}

type ReadonlyUser = DeepReadonly<User>;
// Все свойства readonly, включая вложенные

Типизация функции с перегрузками

function process(value: string): string;
function process(value: number): number;
function process(value: string | number): string | number {
  if (typeof value === "string") {
    return value.toUpperCase();
  }
  return value * 2;
}

Типизация API ответа

interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

interface User {
  id: number;
  name: string;
}

async function fetchUsers(): Promise<ApiResponse<User[]>> {
  const response = await fetch("/api/users");
  return response.json();
}
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
OK

Discriminated Union

type Success<T> = {
  success: true;
  data: T;
};

type Failure = {
  success: false;
  error: string;
};

type Result<T> = Success<T> | Failure;

function handleResult<T>(result: Result<T>) {
  if (result.success) {
    console.log(result.data); // TypeScript знает, что data есть
  } else {
    console.log(result.error); // TypeScript знает, что error есть
  }
}

Mapped Type с фильтрацией

type FilterByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

interface Mixed {
  name: string;
  age: number;
  email: string;
  active: boolean;
}

type StringProps = FilterByType<Mixed, string>;
// { name: string; email: string; }
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
OK

Практикуйся

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