Skip to main content

Вопросы и темы

JS

  • Eventloop (микро и макротаски, приоритет микротасок https://task-sources-test.vercel.app/),
  • requestAnimationFrame
  • Потеря контекста в setTimeout
  • Map/Set, WeakMap/WeakSet их отличие
  • Proxy, Object.defineProperty
  • Как отменить асинхронную операцию?
  • shadowDom, Dom, bom
  • Mutation Observer

Архитектура

  • MVC/MVVM
  • Основные паттерны разработки (solid, kiss etc; фабрика, синглтон, адаптер, observer etc)
  • FSD
  • domain driven
  • Contract First
  • Сравнение PnPM, yarn, npm

Typescript

Any/unknown/never/void

— это конструкция в TypeScript, позволяющая выбирать один тип из двух в зависимости от условия.

Синтаксис:

A extends B ? X : Y

Если A совместим с B, выбирается тип X, иначе — тип Y.

Примеры:

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

type Test1 = IsString<'abc'>; // true
type Test2 = IsString<42>; // false

Для чего нужны:

  • Обобщённые типы (generic types)
  • Варианты для разных типов данных
  • Продвинутое ветвление в типах

Пример использования c типами массивов:

type ElementType<T> = T extends (infer U)[] ? U : T;

type A = ElementType<number[]>; // number
type B = ElementType<string>; // string

Для let - обычный тип, для const - литеральный тип:

let x = 'hello' → x: string
const y = 'hello' → y: 'hello'

let a = 2 → a: number
const b = 2 → b: 2

Для объектов и массивов у const поведение другое — выводится обычный тип, а не литерал.

Утилитарные типы — это встроенные типы TypeScript, упрощающие работу с типами, изменяя их или извлекая информацию из них.

  • Partial<T> — делает все поля типа необязательными.

    type User = { name: string; age: number };
    type PartialUser = Partial<User>; // { name?: string; age?: number; }
  • Required<T> — делает все поля обязательными.

  • Readonly<T> — делает поля только для чтения.

  • Pick<T, K> — берёт только указанные поля из типа.

    type UserName = Pick<User, 'name'>; // { name: string; }
  • Omit<T, K> — убирает указанные поля.

    type UserWithoutAge = Omit<User, 'age'>; // { name: string; }
  • Record<K, T> — создаёт тип объекта с ключами K и значениями типа T.

    type MyObject = Record<'a' | 'b', number>; // { a: number; b: number; }
  • Exclude<T, U> — исключает из T те типы, которые есть в U.

    type A = Exclude<'a' | 'b' | 'c', 'b'>; // 'a' | 'c'
  • Extract<T, U> — выбирает только те типы из T, что есть в U.

    type A = Extract<'a' | 'b' | 'c', 'b' | 'z'>; // 'b'

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

Вся коллекция тут:
https://www.typescriptlang.org/docs/handbook/utility-types.html

Declare

Interface vs Type (определение, разница)

https://github.com/type-challenges/type-challenges

infer

Отличия enum от объекта

as const

Безопасность

  • Как защититься от парсинга?

Задачи

  • Задача: Типизация reduce
  • Задача: Типизация функции сортировки по ключу
  • Задача: fetch с ретраями
  • Задача: Реализация кеширующей функции
  • Задача: Реализация utility-type (например, Pick, Record)
  • Задача: написать функцию, которая оборачивает другую функцию и кеширует ее результат

type MyRecord<T, K> = { [key in T]: K }

Есть посложнее на использование infer'a

Объяснить что делает этот код:

const SomeComponent = isCurrentDomain(Admin) ? React.lazy(() =>
globalThis.System.import("@sbercloud/welcome-widgets").then(module => ({
default: module.default
})) : fallback

Давал задачку на написание функции wait, не справилась. Путает микро и макротаски. не знает синтаксис промиса и связь между промисом и async/await

Прочитать и прорешать задачи на сайте https://www.typescriptlang.org/docs/handbook/intro.html