Forwarded from TypeScript Challenge
Type Challenges #11. Tuple to object
Ссылка на задачу
Условие
Нужно превратить массив в объект, ключами в котором являются элементы исходного массива.
Решение
Прежде всего, уточняем, что ключами объекта могут быть только строки/числа/символы. Вместо перечисления можно использовать встроенный тип
Для получения набора элементов массива используем конструкцию
#easy
Ссылка на задачу
Условие
Нужно превратить массив в объект, ключами в котором являются элементы исходного массива.
Решение
type TupleToObject<T extends ReadonlyArray<string | number | symbol>> = {
[P in T[number]]: P
}
Прежде всего, уточняем, что ключами объекта могут быть только строки/числа/символы. Вместо перечисления можно использовать встроенный тип
PropertyKey
:
type TupleToObject<T extends readonly PropertyKey[]> = {
[P in T[number]]: P
}
Для получения набора элементов массива используем конструкцию
T[number]
.#easy
GitHub
type-challenges/questions/00011-easy-tuple-to-object/README.md at main · type-challenges/type-challenges
Collection of TypeScript type challenges with online judge - type-challenges/type-challenges
👍6
Forwarded from TypeScript Challenge
Type Challenges #189. Awaited
Ссылка на задачу
Условие
Предположим, что у нас есть тип, завернутый в другой тип, например,
Решение
Чтобы решить задачку, нужно понять, какая именно обертка может быть. Посмотрим на тестовые кейсы:
Тут обычные промисы, а также кастомная структура с полем
Для описания обертки нам подойдет встроенная утилита
Но не забываем, что внутри обертки может быть еще одна обертка, поэтому нужно добавить немножко рекурсии:
#easy
Ссылка на задачу
Условие
Предположим, что у нас есть тип, завернутый в другой тип, например,
Promise<string>
. Нужно написать утилиту MyAwaited
для получения внутреннего типа.Решение
Чтобы решить задачку, нужно понять, какая именно обертка может быть. Посмотрим на тестовые кейсы:
type X = Promise<string>
type Y = Promise<{ field: number }>
type Z = Promise<Promise<string | number>>
type Z1 = Promise<Promise<Promise<string | boolean>>>
type T = { then: (onfulfilled: (arg: number) => any) => any }
type cases = [
Expect<Equal<MyAwaited<X>, string>>,
Expect<Equal<MyAwaited<Y>, { field: number }>>,
Expect<Equal<MyAwaited<Z>, string | number>>,
Expect<Equal<MyAwaited<Z1>, string | boolean>>,
Expect<Equal<MyAwaited<T>, number>>,
]
Тут обычные промисы, а также кастомная структура с полем
then
. Кроме того, внутри промиса может быть другой промис и так далее.Для описания обертки нам подойдет встроенная утилита
PromiseLike<T>
, осталось только вывести вложенный тип с помощью infer
:
type MyAwaited<T> = T extends PromiseLike<infer A> ? A : never;
Но не забываем, что внутри обертки может быть еще одна обертка, поэтому нужно добавить немножко рекурсии:
type MyAwaited<T> = T extends PromiseLike<infer A> ? (A extends PromiseLike<infer B> ? MyAwaited<A> : A) : never;
#easy
GitHub
type-challenges/questions/00189-easy-awaited/README.md at main · type-challenges/type-challenges
Collection of TypeScript type challenges with online judge - type-challenges/type-challenges
👍2
Forwarded from TypeScript Challenge
Type Challenges. Уровень easy. Резюме
Итак, мы прорешали 13 задачек уровня easy.
4 - Pick
7 - Readonly
11 - Tuple to Object
14 - First of Array
18 - Length of Tuple
43 - Exclude
189 - Awaited
268 - If
533 - Concat
898 - Includes
3057 - Push
3060 - Unshift
3312 - Parameters
Проведем небольшую ретроспективу и отметим основные моменты решений.
🟢 1. extends
Самое популярное ключевое слово в решениях.
Используется для уточнения типов в дженериках (9 задач):
Используется для сравнения в условных типах (2 задачи):
Используется в комбинации с ключевым словом
🟢 2. Копирование ключей объекта (3 задачи)
Используется для создания Mapped Types, когда новый тип повторяет ключи исходного
🟢 3. keyof
Ключевое слово для получения набора из всех ключей объекта (2 задачи)
🟢 4. Превращение массива типов в перечисление типов(1 задача)
Используем конструкцию
🟢 5. Использование readonly структур для работы с кортежами (3 задачи)
🟢 6. Деструктуризация массивов (5 задач)
#easy
Итак, мы прорешали 13 задачек уровня easy.
4 - Pick
7 - Readonly
11 - Tuple to Object
14 - First of Array
18 - Length of Tuple
43 - Exclude
189 - Awaited
268 - If
533 - Concat
898 - Includes
3057 - Push
3060 - Unshift
3312 - Parameters
Проведем небольшую ретроспективу и отметим основные моменты решений.
🟢 1. extends
Самое популярное ключевое слово в решениях.
Используется для уточнения типов в дженериках (9 задач):
type MyPick<T, K extends keyof T>
Используется для сравнения в условных типах (2 задачи):
type If<C extends boolean, T, F> = C extends true ? T : F
Используется в комбинации с ключевым словом
infer
для выведения одних типов из других (4 задачи):
type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never
🟢 2. Копирование ключей объекта (3 задачи)
Используется для создания Mapped Types, когда новый тип повторяет ключи исходного
type MyReadonly<T> = {
readonly [K in keyof T]: T[K]
}
🟢 3. keyof
Ключевое слово для получения набора из всех ключей объекта (2 задачи)
type MyPick<T, K extends keyof T> = {
[P in K]: T[P]
}
🟢 4. Превращение массива типов в перечисление типов(1 задача)
Используем конструкцию
T[number]
.
type TupleToObject<T extends ReadonlyArray<string | number | symbol>> = {
[P in T[number]]: P
}
🟢 5. Использование readonly структур для работы с кортежами (3 задачи)
type Length<T extends readonly any[]> = T['length']
🟢 6. Деструктуризация массивов (5 задач)
type Push<T extends any[], U> = [...T, U]
#easy
Telegram
TypeScript Challenge
Type Challenges #4. Pick
Ссылка на задачу
Ссылка на песочницу с тестами
Нужно реализовать своими силами встроенную утилиту Pick<T, K>.
Утилита принимает тип T и создает на его основе новый тип, состоящий из свойств, которые указаны в наборе K.
Решение:…
Ссылка на задачу
Ссылка на песочницу с тестами
Нужно реализовать своими силами встроенную утилиту Pick<T, K>.
Утилита принимает тип T и создает на его основе новый тип, состоящий из свойств, которые указаны в наборе K.
Решение:…
👍4