3,9 Мб, mp4,
224x224, 1:42
224x224, 1:42
Хочу сколотить капитал. И учиться.
54 Кб, 1279x697
Решал очередную задачу по Тайпскрипту - аж 33 минуты! Сайт ни в какую не хотел принимать мой, написанный за 2 минуты, изначальный вариант - "Record<infer K, any>...[K] extends [never]": не проходил тест с "object". Пришлось проверять [keyof T] и Record<_, any> поменять на Record<_, string>. Почему-то это сработало. Подбирал комбинаторно.
Сегодня ничего не заработал.
money:
wallet - [0_000] RUB
crypto - [0_000] $
Сегодня ничего не заработал.
money:
wallet - [0_000] RUB
crypto - [0_000] $
Снова Тайпскрипт.
Первую задачу решил слёту. Она простая.
Над второй сидел больше 20 минут, пытаясь решить через вереницу тернарных операторов, отсеивая тип за типом. Никак не получалось отличать "never" от "any". В итоге нашел объяснение в Интернете. Проверка через условные типы - "0 extends (1 & T)" - работает для any: почему-то Тайпскрипт мёрджит "1 & any" -> "any", поэтому срабатывает проверка "0 extends any". С остальными типами единица остаётся.
Сегодня ничего не заработал.
money:
wallet - [0_000] RUB
crypto - [0_000] $
Первую задачу решил слёту. Она простая.
Над второй сидел больше 20 минут, пытаясь решить через вереницу тернарных операторов, отсеивая тип за типом. Никак не получалось отличать "never" от "any". В итоге нашел объяснение в Интернете. Проверка через условные типы - "0 extends (1 & T)" - работает для any: почему-то Тайпскрипт мёрджит "1 & any" -> "any", поэтому срабатывает проверка "0 extends any". С остальными типами единица остаётся.
Сегодня ничего не заработал.
money:
wallet - [0_000] RUB
crypto - [0_000] $
>>1814
Разобрался. "any" - супертип и поглощает (расширяет) все подтипы в юнитах.
В документации написано на примере строки общим типом и константых строк. Запустил пример в плейграунде.
На сегодня всё.
Разобрался. "any" - супертип и поглощает (расширяет) все подтипы в юнитах.
В документации написано на примере строки общим типом и константых строк. Запустил пример в плейграунде.
На сегодня всё.
Тайпскрипт. Три задачки.
Первая задача тривиальная.
Решение для второй задачи написал сразу, но тесты не проходили. Спустя 12 минут добавил значение по умолчанию для третьего типа (A extends any[] = []) - и всё прошло.
Третья задача тоже простая, но снова не понятно, почему он не подхватывает "infer F as string" и "...infer R as string[]", если изначально "T extends string[]". Может в следующих версиях исправят.
Сегодня заработал 10 000 рублей - 8 000 рублей в копилку.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Первая задача тривиальная.
Решение для второй задачи написал сразу, но тесты не проходили. Спустя 12 минут добавил значение по умолчанию для третьего типа (A extends any[] = []) - и всё прошло.
Третья задача тоже простая, но снова не понятно, почему он не подхватывает "infer F as string" и "...infer R as string[]", если изначально "T extends string[]". Может в следующих версиях исправят.
Сегодня заработал 10 000 рублей - 8 000 рублей в копилку.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Тайпскрипт. Две задачи.
Над первой пришлось немного покумекать, но в целом ничего сложного. Не сразу сообразил, как правильно решить через рекурсию. Надо было увеличивать как результирующее множество, так и множество-счетчик.
Вторая задача посложнее. Проверяем, дошли ли мы в итерации по кортежу до конца: 1. если да - возвращаем множество-аккумулятор; 2. если нет - проверяем, совпадает ли текущий тип с заданным (через строгое сравнение); 2.1. если совпадает - добавляем тип в множество-аккумулятор и вызываем проверку рекурсивно с оставшимися типами; 2.2 если не совпадает - оставляем множество-аккумулятор в прежнем состоянии и вызываем проверку рекурсивно с оставшимися типами.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Над первой пришлось немного покумекать, но в целом ничего сложного. Не сразу сообразил, как правильно решить через рекурсию. Надо было увеличивать как результирующее множество, так и множество-счетчик.
Вторая задача посложнее. Проверяем, дошли ли мы в итерации по кортежу до конца: 1. если да - возвращаем множество-аккумулятор; 2. если нет - проверяем, совпадает ли текущий тип с заданным (через строгое сравнение); 2.1. если совпадает - добавляем тип в множество-аккумулятор и вызываем проверку рекурсивно с оставшимися типами; 2.2 если не совпадает - оставляем множество-аккумулятор в прежнем состоянии и вызываем проверку рекурсивно с оставшимися типами.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
19 Кб, 715x261
>>2066
1. [any] extends [number] ? 1 : 2; // 1
2. any extends number ? 1 : 2; // 1 | 2
Я так и не смог разобраться, почему без скобок запиналось на "any extends number" во второй задаче. Эх, вот бы кто-нибудь умный объяснил...
1. [any] extends [number] ? 1 : 2; // 1
2. any extends number ? 1 : 2; // 1 | 2
Я так и не смог разобраться, почему без скобок запиналось на "any extends number" во второй задаче. Эх, вот бы кто-нибудь умный объяснил...
22 Кб, 523x246
>>2071
Вот такой результат без скобок "[1, 2] | [1, 2, any]". Со скобками же множества объединяются "(1 | 2 | any)[]" - правильно понял?
Вот такой результат без скобок "[1, 2] | [1, 2, any]". Со скобками же множества объединяются "(1 | 2 | any)[]" - правильно понял?
Тайпскрипт. Две задачи.
За 15 минут подобрал элегантное решение для первой задачи. Интересно, можно ли это решить без внедрения счётчика.
Вторую задачу решил безобразно, топорно, в лоб, но зато за 5 минут. В этом решении можно было бы вынести логику увеличения счётчика отдельно, так как она повторяется для каждого слагаемого. Опять-таки, хотелось бы найти решение без счётчиков, но пока не получается.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
За 15 минут подобрал элегантное решение для первой задачи. Интересно, можно ли это решить без внедрения счётчика.
Вторую задачу решил безобразно, топорно, в лоб, но зато за 5 минут. В этом решении можно было бы вынести логику увеличения счётчика отдельно, так как она повторяется для каждого слагаемого. Опять-таки, хотелось бы найти решение без счётчиков, но пока не получается.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Тайпскрипт. Две задачи.
Первая задача решена за 4 минуты. После прочтения примечания "we can just consider smaller numbers" решение сразу прилетело в голову.
Над второй задачей бился 30 минут, так и не решив. Почему не проходят тесты? Должно же вернуться пересечение "A & B & C", а возвращается объединение "A | B | C". Вот бы подсказочку. Оставлю на завтра.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
>>2257
https://bigfrontend.dev/
Первая задача решена за 4 минуты. После прочтения примечания "we can just consider smaller numbers" решение сразу прилетело в голову.
Над второй задачей бился 30 минут, так и не решив. Почему не проходят тесты? Должно же вернуться пересечение "A & B & C", а возвращается объединение "A | B | C". Вот бы подсказочку. Оставлю на завтра.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
>>2257
https://bigfrontend.dev/
51 Кб, 1278x727
Тайпскрипт. Одна вчерашняя нерешенная задача.
"Разобрался" со вчерашней задачей. Вот такое неочевидное решение.
Больше не получилось - сайт упал.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
"Разобрался" со вчерашней задачей. Вот такое неочевидное решение.
Больше не получилось - сайт упал.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Тайпскрипт. Поскольку вчера BFE внезапно отвалился и был недоступен несколько часов, параллельно начал решать задачи на "type-challanges". Вообще, Тайпскрипту не хочу уделять больше двух месяцев, поэтому постепенно буду увеличивать количество решаемых задач в день. Небольшой прогресс ощущается. Две задачи.
Обе задачи простые, похожие уже попадалась на BFE.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Обе задачи простые, похожие уже попадалась на BFE.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Тайпскрипт. Одна клятая задача.
Около часа решал. Разъясните, почему моё решение не проходит тесты на BFE? В TS Playground всё отлично. Версии компилятора разнятся? Что именно не так? Поскольку в плейграунде тесты успешно прошли, засчитаю как решённую.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Около часа решал. Разъясните, почему моё решение не проходит тесты на BFE? В TS Playground всё отлично. Версии компилятора разнятся? Что именно не так? Поскольку в плейграунде тесты успешно прошли, засчитаю как решённую.
Сегодня ничего не заработал.
money:
wallet - [8_000] RUB
crypto - [0_000] $
Тайпскрипт. Три задачи.
Equal. Проверка на соответствие двух типов через два симметричных кортежа. Решение подсмотрел. Эта проверка пригодилась бы в предыдущей задаче, где нужно было найти индекс элемента в кортеже. У меня было другое решение - более громоздкое. Проблему в таких проверках составляют два типа: "never" и "any".
TupleToObject. Принимаем кортеж типа PropertyKey и через T[number] получаем объединение всех элементов кортежа, через которые итерируется - [K in T[number]].
First. Совсем всё просто: если кортеж пустой (т.е T['length'] extends 0) - возвращаем "never", если есть хотя бы один элемент - возвращаем первый (T[0]).
Equal. Проверка на соответствие двух типов через два симметричных кортежа. Решение подсмотрел. Эта проверка пригодилась бы в предыдущей задаче, где нужно было найти индекс элемента в кортеже. У меня было другое решение - более громоздкое. Проблему в таких проверках составляют два типа: "never" и "any".
TupleToObject. Принимаем кортеж типа PropertyKey и через T[number] получаем объединение всех элементов кортежа, через которые итерируется - [K in T[number]].
First. Совсем всё просто: если кортеж пустой (т.е T['length'] extends 0) - возвращаем "never", если есть хотя бы один элемент - возвращаем первый (T[0]).
Тайпскрипт. Три задачи.
Trim. После своего решения, посмотрел другие. Проверку можно было делать не по отдельности, а атомарно - "T extends ` ${String}` |`${String} `". Я до такого не догадался.
ReplaceAll. Решил через добавление результирующего типа, которое по умолчанию пустая строка. Пришлось добавить ещё одну проверку (S extends Tail) на случай, когда BFE добавлял пустую строку и моё решение бесконечно вызывалось через рекурсию, потому что хвост не укорачивался. Посмотрел другие решения. Можно было решать без добавления дополнительного типа. Не догадался из-за неочевидного поведения такой конструкции: "S extends `${infer A}${F}${infer B}`". Чему будет равно A? Логично предположить, что первому символу в строке, но по какой-то причине возвращается пустая строка и первый символ магнитится к F. Это из-за "infer". Но всё равно выходит магия Тайпскрипта. Запутался. Добавил в закладки материал на эту тему, почитаю позже.
Exclude. Ну здесь вообще элементарно. Когда мы проверяем объединение через "extends", проверка осуществляется итеративно по каждому отдельному члену. Возвращается тоже объединение, но при этом "never" в объединении игнорируется. Поэтому всё выполняется как надо.
>>2919
JS изучал, но он в TS совсем не помощник.
Trim. После своего решения, посмотрел другие. Проверку можно было делать не по отдельности, а атомарно - "T extends ` ${String}` |`${String} `". Я до такого не догадался.
ReplaceAll. Решил через добавление результирующего типа, которое по умолчанию пустая строка. Пришлось добавить ещё одну проверку (S extends Tail) на случай, когда BFE добавлял пустую строку и моё решение бесконечно вызывалось через рекурсию, потому что хвост не укорачивался. Посмотрел другие решения. Можно было решать без добавления дополнительного типа. Не догадался из-за неочевидного поведения такой конструкции: "S extends `${infer A}${F}${infer B}`". Чему будет равно A? Логично предположить, что первому символу в строке, но по какой-то причине возвращается пустая строка и первый символ магнитится к F. Это из-за "infer". Но всё равно выходит магия Тайпскрипта. Запутался. Добавил в закладки материал на эту тему, почитаю позже.
Exclude. Ну здесь вообще элементарно. Когда мы проверяем объединение через "extends", проверка осуществляется итеративно по каждому отдельному члену. Возвращается тоже объединение, но при этом "never" в объединении игнорируется. Поэтому всё выполняется как надо.
>>2919
JS изучал, но он в TS совсем не помощник.
Тайпскрипт. Две задачи.
MyAwaited. Не проходили тесты на проверку по простому Promise (т.к "{ then: (onfulfilled: (arg: number) => any) => any }"- тоже промис). Нужно было использовать встроенный тип PromiseLike.
If. Без комментариев.
Прочитал в руководстве статью "Template Literal Types" и "Using type predicates".
Основное:
- если передать объединение в строковой шаблон, вернется новое объединение с каждым интерполированным членом старого объединения: `${A | B}_str` => 'A_str' | 'B_str';
- два встроенных полезных типа: Uppercase<string> и Lowercase<string>;
- можно проверять неизвестные типы через предикат: (arg): arg is MyType => {...} - это полезно, когда мы получаем неизвестные данные (с какого-нибудь эндпоинта, в котором мы не уверены) и нам нужно провалидировать эти данные;
- полезный метод assert(...), заимствованный из C: сначала объявляем "declare function assert(value: unknown): asserts value;" (т.ё asserts value is true), а потом используем "assert(1 === 2)" - выкинет ошибку во время компиляции.
Про поведение с "infer" в руководстве не нашёл.
В следующие дни пробегусь по "release-notes" начиная с версии 3.5.
MyAwaited. Не проходили тесты на проверку по простому Promise (т.к "{ then: (onfulfilled: (arg: number) => any) => any }"- тоже промис). Нужно было использовать встроенный тип PromiseLike.
If. Без комментариев.
Прочитал в руководстве статью "Template Literal Types" и "Using type predicates".
Основное:
- если передать объединение в строковой шаблон, вернется новое объединение с каждым интерполированным членом старого объединения: `${A | B}_str` => 'A_str' | 'B_str';
- два встроенных полезных типа: Uppercase<string> и Lowercase<string>;
- можно проверять неизвестные типы через предикат: (arg): arg is MyType => {...} - это полезно, когда мы получаем неизвестные данные (с какого-нибудь эндпоинта, в котором мы не уверены) и нам нужно провалидировать эти данные;
- полезный метод assert(...), заимствованный из C: сначала объявляем "declare function assert(value: unknown): asserts value;" (т.ё asserts value is true), а потом используем "assert(1 === 2)" - выкинет ошибку во время компиляции.
Про поведение с "infer" в руководстве не нашёл.
В следующие дни пробегусь по "release-notes" начиная с версии 3.5.
Тайпскрипт. Две задачи и release-notes 3.5.
Concat. Конкатенация кортежей. Пришлось добавить свойство "readonly" т.к компилятор ругался на "[1] as const", когда было просто "T extends any".
Includes. Вхождение в кортеж. Решение простое, но если заглянуть в обсуждение к этой задаче, можно найти ещё одно экзотическое сравнение на соответствие двух типов (Equal): "(<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false".
Прочитал про отличия "any" от "unknown". Как понял, "any" - отключает вообще проверку типизации, а "unknown" - тоже отключает, но делает это более безопасно: "unknown" нельзя присвоить в любой другой тип (в отличии от any) и нельзя вызвать свойство/метод у "unknown". Пока что понимание такое.
release-notes/typescript-3-5.html:
- оптимизирована компиляция, увеличена скорость (в project references?);
- появился встроенный Omit-тип, который исключает свойство;
- добавлено глобальное объявление типов для UMD-модулей (без тройного слеша)?.
Concat. Конкатенация кортежей. Пришлось добавить свойство "readonly" т.к компилятор ругался на "[1] as const", когда было просто "T extends any".
Includes. Вхождение в кортеж. Решение простое, но если заглянуть в обсуждение к этой задаче, можно найти ещё одно экзотическое сравнение на соответствие двух типов (Equal): "(<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false".
Прочитал про отличия "any" от "unknown". Как понял, "any" - отключает вообще проверку типизации, а "unknown" - тоже отключает, но делает это более безопасно: "unknown" нельзя присвоить в любой другой тип (в отличии от any) и нельзя вызвать свойство/метод у "unknown". Пока что понимание такое.
release-notes/typescript-3-5.html:
- оптимизирована компиляция, увеличена скорость (в project references?);
- появился встроенный Omit-тип, который исключает свойство;
- добавлено глобальное объявление типов для UMD-модулей (без тройного слеша)?.
Тайпскрипт. Две задачи и release-notes 3.6.
Parameters. Кортеж типов параметров функции. Используем infer и остаточные параметры. Ничего нового.
Slice. Срез элементов кортежа. Получилось непросто. Пришлось задействовать проверку LessThan (которую уже реализовывал в предыдущей задаче). Своим решением доволен. В первый день я бы такое не решил - прогресс налицо.
На этом этапе все задачи из секции "easy" решены. Впереди "medium".
release-notes/typescript-3-6.html:
- добавили проверку возвращаемого типа функцией-генератором;
- улучшили развёртывание через array spread;
- добавили проверку на наличие дженерика "Promise<T>".
Parameters. Кортеж типов параметров функции. Используем infer и остаточные параметры. Ничего нового.
Slice. Срез элементов кортежа. Получилось непросто. Пришлось задействовать проверку LessThan (которую уже реализовывал в предыдущей задаче). Своим решением доволен. В первый день я бы такое не решил - прогресс налицо.
На этом этапе все задачи из секции "easy" решены. Впереди "medium".
release-notes/typescript-3-6.html:
- добавили проверку возвращаемого типа функцией-генератором;
- улучшили развёртывание через array spread;
- добавили проверку на наличие дженерика "Promise<T>".
109 Кб, 1055x742
Тайпскрипт. Одна задача и release-notes 3.7.
Last of Array. Первым пришло в голову такое решение. Хотя имеется альтернативное - "type Last<T extends any[]> = T extends [...infer _, infer B] ? B : never".
Стали попадаться задачи, которые уже решал. Проскакиваю их. Ожидал большего от "medium". От этих задач уже мало проку, надеюсь на изменения по мере увеличения сложности.
release-notes/typescript-3-7.html:
- добавили "optianal chaining" (foo?.bar.baz());
- добавили нулевой оператор (foo ?? bar());
- добавили assertion (assert(someValue === 42)), который делает проверку на этапе компиляции;
- добавили возможность через флаг "--declaration", который позволяет автоматически генерировать d.ts из исходников .js, используя JSDoc;
- возможность игнорировать проверку всего файла через комментарий "// @ts-nocheck".
Last of Array. Первым пришло в голову такое решение. Хотя имеется альтернативное - "type Last<T extends any[]> = T extends [...infer _, infer B] ? B : never".
Стали попадаться задачи, которые уже решал. Проскакиваю их. Ожидал большего от "medium". От этих задач уже мало проку, надеюсь на изменения по мере увеличения сложности.
release-notes/typescript-3-7.html:
- добавили "optianal chaining" (foo?.bar.baz());
- добавили нулевой оператор (foo ?? bar());
- добавили assertion (assert(someValue === 42)), который делает проверку на этапе компиляции;
- добавили возможность через флаг "--declaration", который позволяет автоматически генерировать d.ts из исходников .js, используя JSDoc;
- возможность игнорировать проверку всего файла через комментарий "// @ts-nocheck".
Тайпскрипт. Три задачи и release-notes.
Promise.all. Наконец что-то сложное! Во-первых, уже нужно было не создать тип/интерфейс, а объявить метод. Во-вторых, избавляемся от объединения через "[...T]". В-третьих, используем встроенный тип Awaited, который рекурсивно извлекает возвращаемый тип у промиса.
release-notes/typescript-3-8.html:
- добавили type-only imports/exports - "import/export type { SomeThing } from "./some-module.js"";
- добавили инкапсуляцию полей через # у классов (как у наивного EcmaScript);
- доступен top-level await внутри модуля (export {}; => await f()).
Promise.all. Наконец что-то сложное! Во-первых, уже нужно было не создать тип/интерфейс, а объявить метод. Во-вторых, избавляемся от объединения через "[...T]". В-третьих, используем встроенный тип Awaited, который рекурсивно извлекает возвращаемый тип у промиса.
release-notes/typescript-3-8.html:
- добавили type-only imports/exports - "import/export type { SomeThing } from "./some-module.js"";
- добавили инкапсуляцию полей через # у классов (как у наивного EcmaScript);
- доступен top-level await внутри модуля (export {}; => await f()).
Тайпскрипт. Две задачи и release-notes.
Trim. Задача уже попадалась на BFE. В этот раз решение чище.
Capitalize. Возведение первого символа в верхний регистр.
Нашел интерфейс нормальный на гитхабпейджес. Следующие задачи попробую решать через него.
release-notes/typescript-3-9.html:
- пофиксии типизацию возвращаемых значений Promice.all/race;
- добавлена проверка "// @ts-expect-error" - выводит ошибку, когда её нет, и игнорирует, когда она есть;
- добавлен not-null aseertion оператор (foo!.baz).
Trim. Задача уже попадалась на BFE. В этот раз решение чище.
Capitalize. Возведение первого символа в верхний регистр.
Нашел интерфейс нормальный на гитхабпейджес. Следующие задачи попробую решать через него.
release-notes/typescript-3-9.html:
- пофиксии типизацию возвращаемых значений Promice.all/race;
- добавлена проверка "// @ts-expect-error" - выводит ошибку, когда её нет, и игнорирует, когда она есть;
- добавлен not-null aseertion оператор (foo!.baz).
Тайпскрипт. Две задачи и release-notes.
Воспользовался интерфейсом, который написан на React и развернут на Github Pages.
Деньги пока не копятся, нужно это исправить с начала следующего года.
release-notes/typescript-4-0.html:
- добавлена возможность использовать spread-оператор вместе с дженериком (я уже пользовался этим в решении предыдущей задачи), чтобы описывать функции с переменным количеством аргументов;
- добавлены Labeled Tuple Elements (foo(...args: [first: string, second: number]));
- добавлены короткие операторы присвоения типа таких - (values ??= []) и (a ||= b) - очень полезно (проверил, они, оказывается, и в нативном JS есть);
- установили catch-error в unknown по умолчанию вместо any;
- добавили фишки в редактор кода с автоматическим редактированием.
Воспользовался интерфейсом, который написан на React и развернут на Github Pages.
Деньги пока не копятся, нужно это исправить с начала следующего года.
release-notes/typescript-4-0.html:
- добавлена возможность использовать spread-оператор вместе с дженериком (я уже пользовался этим в решении предыдущей задачи), чтобы описывать функции с переменным количеством аргументов;
- добавлены Labeled Tuple Elements (foo(...args: [first: string, second: number]));
- добавлены короткие операторы присвоения типа таких - (values ??= []) и (a ||= b) - очень полезно (проверил, они, оказывается, и в нативном JS есть);
- установили catch-error в unknown по умолчанию вместо any;
- добавили фишки в редактор кода с автоматическим редактированием.
93 Кб, 1264x783
Тайпскрипт. Одна задача и release-notes.
release-notes/typescript-4-1.html:
- добавили `${тип}${строкового}${литерала}`;
- добавили оператор "as" в переборе ключей ([K in keyof T as NewKeyType]).
release-notes/typescript-4-1.html:
- добавили `${тип}${строкового}${литерала}`;
- добавили оператор "as" в переборе ключей ([K in keyof T as NewKeyType]).
61 Кб, 1271x730
Обновить тредТайпскрипт. Одна задача и release-notes.
Пока что в учёбе "еду на холостых", много стресса в жизни. Нужно перетерпеть чёрную полосу. Морально-психологическое состояние - 3 из 10.
Permutation. Не сразу решил. Сначала нам нужно убрать "never", чтобы он не срабатывал как супертип, когда вызывается рекурсивно Permutation и разворачивается результат в кортеж. Ещё был задействован встроенный тип Exclude, чтобы исключить итерируемый ключ. Вместе с тем клонировали оригинальное объединение T в K, чтобы передавать его первым параметром в Exclude, так как в T находится итерируемый член объединения.
release-notes/typescript-4-2.html:
- добавлен strict right side operator ("foo" in 42 - ошибка);
- добавлен абстрактный модификатор на сигнатуру конструктора (var a: abstract new () => Something = b);
- при деструктуризации массива можно использовать _НазваниеСПодчеркавания, чтобы показать компилятору о неиспользовании этой переменной в будущем ([_fist, second] = arr).
Пока что в учёбе "еду на холостых", много стресса в жизни. Нужно перетерпеть чёрную полосу. Морально-психологическое состояние - 3 из 10.
Permutation. Не сразу решил. Сначала нам нужно убрать "never", чтобы он не срабатывал как супертип, когда вызывается рекурсивно Permutation и разворачивается результат в кортеж. Ещё был задействован встроенный тип Exclude, чтобы исключить итерируемый ключ. Вместе с тем клонировали оригинальное объединение T в K, чтобы передавать его первым параметром в Exclude, так как в T находится итерируемый член объединения.
release-notes/typescript-4-2.html:
- добавлен strict right side operator ("foo" in 42 - ошибка);
- добавлен абстрактный модификатор на сигнатуру конструктора (var a: abstract new () => Something = b);
- при деструктуризации массива можно использовать _НазваниеСПодчеркавания, чтобы показать компилятору о неиспользовании этой переменной в будущем ([_fist, second] = arr).