Вопросы и темы
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