#тип дня
Говоришь такой коллеге: «Ты зачем столько классов насоздавал для такой простой вещи? Используй CSS-переменные».
А он приходит к тебе с картинкой выше и грустный весь.
Что мы делаем в таком случае?
Да очень просто, дополняем интерфейс CSSProperties, чтобы до реакта, наконец, дошло:
Пруф: песочница.
Странно, конечно, что это не из коробки всё.
#css #types #react #typescript
Говоришь такой коллеге: «Ты зачем столько классов насоздавал для такой простой вещи? Используй CSS-переменные».
А он приходит к тебе с картинкой выше и грустный весь.
Что мы делаем в таком случае?
Да очень просто, дополняем интерфейс CSSProperties, чтобы до реакта, наконец, дошло:
declare module 'react' {
interface CSSProperties {
[key: `--${string}`]: string | number
}
}
Пруф: песочница.
Странно, конечно, что это не из коробки всё.
#css #types #react #typescript
#тип дня
Вышел TypeScript 5.4.
А это что значит? Что у нас теперь есть служебный тип NoInfer.
Коротко, зачем он нужен: с его указанием TS больше не будет пытаться угадать тип передаваемого аргумента. Например, если не указать тип массива
Чтобы такого не происходило, есть два пути. Первый:
Ну такое, многословно и D больше нигде в коде не используется. Вот тут и приходит на помощь NoInfer:
Всё, тип массива определён как, практически, у константы ["red", "yellow", "green"] и передать "blue" уже не выйдет.
Естественно, улучшений и нововведений в TS 5.4 сильно больше, рекомендую прочитать заметки о выпуске: https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/
#typescript #generics
Вышел TypeScript 5.4.
А это что значит? Что у нас теперь есть служебный тип NoInfer.
Коротко, зачем он нужен: с его указанием TS больше не будет пытаться угадать тип передаваемого аргумента. Например, если не указать тип массива
["red", "yellow", "green"]
, TS определит его как string[]
и разрешит запихнуть туда значение "blue"
или, что хуже, позволить вашему коду попытаться, например, это самое значение в нём найти:
function createStreetLight<C extends string>(colors: C[], defaultColor?: C) {
// ...
}
createStreetLight(["red", "yellow", "green"], "blue");
Чтобы такого не происходило, есть два пути. Первый:
function createStreetLight<C extends string, D extends C>(colors: C[], defaultColor?: D) {
}
createStreetLight(["red", "yellow", "green"], "blue");
// ~~~~~~
// error!
// Argument of type '"blue"' is not assignable to parameter of type '"red" | "yellow" | "green" | undefined'.
Ну такое, многословно и D больше нигде в коде не используется. Вот тут и приходит на помощь NoInfer:
function createStreetLight<C extends string>(colors: C[], defaultColor?: NoInfer<C>) {
// ...
}
createStreetLight(["red", "yellow", "green"], "blue");
// ~~~~~~
// error!
// Argument of type '"blue"' is not assignable to parameter of type '"red" | "yellow" | "green" | undefined'.
Всё, тип массива определён как, практически, у константы ["red", "yellow", "green"] и передать "blue" уже не выйдет.
Естественно, улучшений и нововведений в TS 5.4 сильно больше, рекомендую прочитать заметки о выпуске: https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/
#typescript #generics
#ссылка дня
Типизирование React-компонентов, рефов и хуков может обернуться большой болью. Особенно если в первый раз. Но к счастью, у нас есть GitHub, который добрые люди используют не только как хранилище кода, но и как идеальный универсальный блог :)
Встречайте: https://github.com/typescript-cheatsheets/react
Буквально, из описания: «Cheatsheets for experienced React developers getting started with TypeScript».
Впрочем, у ребят есть и более привычная веб-версия, разбитая на секции: https://react-typescript-cheatsheet.netlify.app/
Мне, например, недавно понадобилось сделать полиморфичный компонент, который в зависимости от условий мог становиться то ссылкой, то кнопкой (какой прекрасный повод для холивара). Я не нашёл решения непосредственно здесь, зато нашёл в обсуждениях и PR. Что тоже показывает, как удобен GitHub для коллективного блога.
В общем, всем типов, котаны.
#typescript #react #бородач
Типизирование React-компонентов, рефов и хуков может обернуться большой болью. Особенно если в первый раз. Но к счастью, у нас есть GitHub, который добрые люди используют не только как хранилище кода, но и как идеальный универсальный блог :)
Встречайте: https://github.com/typescript-cheatsheets/react
Буквально, из описания: «Cheatsheets for experienced React developers getting started with TypeScript».
Впрочем, у ребят есть и более привычная веб-версия, разбитая на секции: https://react-typescript-cheatsheet.netlify.app/
Мне, например, недавно понадобилось сделать полиморфичный компонент, который в зависимости от условий мог становиться то ссылкой, то кнопкой (какой прекрасный повод для холивара). Я не нашёл решения непосредственно здесь, зато нашёл в обсуждениях и PR. Что тоже показывает, как удобен GitHub для коллективного блога.
В общем, всем типов, котаны.
#typescript #react #бородач
#библиотека дня
— А что, если типы надо проверять в рантайме?
— Да не, херня какая-то...
Впрочем, создателям библиотеки Typia так совсем не кажется. Да и вам, в целом, казаться не должно: TypeScript, конечно, большой молодец, но типы проверяет только на этапе компиляции. И, конечно же, мы все верим в святые контракты :)
Библиотека предлагает не только проверку входящих данных, но и соответствие JSON описанию.
Есть как простые is и equals, возвращающие логическое соответствие, так и assert и assertEquals, кидающие ошибку.
Отличие is от equals в том, что is менее строгий и позволяет расширение объекта свойствами, которых нет в интерфейсе. Но описанные при этом должны соответствовать.
Обратили внимание? Схема не нужна!
Как-то так. Кто использовал уже?
#typescript #types
— А что, если типы надо проверять в рантайме?
— Да не, херня какая-то...
Впрочем, создателям библиотеки Typia так совсем не кажется. Да и вам, в целом, казаться не должно: TypeScript, конечно, большой молодец, но типы проверяет только на этапе компиляции. И, конечно же, мы все верим в святые контракты :)
Библиотека предлагает не только проверку входящих данных, но и соответствие JSON описанию.
Есть как простые is и equals, возвращающие логическое соответствие, так и assert и assertEquals, кидающие ошибку.
Отличие is от equals в том, что is менее строгий и позволяет расширение объекта свойствами, которых нет в интерфейсе. Но описанные при этом должны соответствовать.
const input: unknown = {
id: v4(),
email: "samchon.github@gmail.com",
age: 30,
extra: "superfluous property", // extra
};
const is: boolean = typia.is<IMember>(input);const
equals: boolean = typia.equals<IMember>(input);
console.log(is, equals); // true, false
Обратили внимание? Схема не нужна!
Как-то так. Кто использовал уже?
#typescript #types
#инструмент дня
Если меня спросят, на чем я стал бы делать ранний прототип, я бы ответил Drupal. Ну или Ruby on Rails. Ну просто потому что я их знаю. На Drupal вообще мышкой можно все накликать и получить рабочий API.
Но, конечно, это уже сравнительно оторвано от реальности :) Простой CRUD aka Create-Read-Update-Delete можно собрать тысячей разных способов.
Так что стоит принести ещё один: Remult.
https://remult.dev/
Remult использует всю мощь декораторов TypeScript для описания своих т. н. сущностей, которые потом станут моделями.
После чего остается только зарегистрировать созданную сущность в сервере на, например, express и получить готовый CRUD API.
Останется дело за фронтендом, который автоматом тут не генерируется, зато вам доступно множество хелперов для управления своими сущностями.
Прекрасная документация, отличные пошаговые инструкции к разным фреймворкам. Ребята однозначно старались.
Горячая рекомендация, в целом.
#typescript #crud
Если меня спросят, на чем я стал бы делать ранний прототип, я бы ответил Drupal. Ну или Ruby on Rails. Ну просто потому что я их знаю. На Drupal вообще мышкой можно все накликать и получить рабочий API.
Но, конечно, это уже сравнительно оторвано от реальности :) Простой CRUD aka Create-Read-Update-Delete можно собрать тысячей разных способов.
Так что стоит принести ещё один: Remult.
https://remult.dev/
Remult использует всю мощь декораторов TypeScript для описания своих т. н. сущностей, которые потом станут моделями.
import { Entity, Fields } from "remult"
@Entity("tasks", {
allowApiCrud: true
})
export class Task {
@Fields.cuid()
id = ""
@Fields.string()
title = ""
@Fields.boolean()
completed = false
@Fields.createdAt()
createdAt?: Date
}
После чего остается только зарегистрировать созданную сущность в сервере на, например, express и получить готовый CRUD API.
Останется дело за фронтендом, который автоматом тут не генерируется, зато вам доступно множество хелперов для управления своими сущностями.
Прекрасная документация, отличные пошаговые инструкции к разным фреймворкам. Ребята однозначно старались.
Горячая рекомендация, в целом.
#typescript #crud
#инструмент дня
Ладно, мы все можем согласиться, что у TypeScript замечательный офсайт, прекрасная документация и удобная песочница, но в мире есть сотни тысяч JS-библиотек и десятки тысяч из них либо написаны на TS, либо имеют выделенные типы.
А единой документации по этим типам нет!
Точнее, не было, но теперь вышел https://tsdocs.dev/
Это система поиска по существующим пакетам с типами. Она установит нужный пакет, распарсит типы и JSDoc и отобразит в удобном формате.
К слову, котаны, что вы предпочитаете по cmd- (ctrl)-click в редакторе? Прыгать к имплементации, или к типам?
Я вот — к имплементации, прыгать к типам меня раздражает.
#typescript #dts #types #doc #бородач
Ладно, мы все можем согласиться, что у TypeScript замечательный офсайт, прекрасная документация и удобная песочница, но в мире есть сотни тысяч JS-библиотек и десятки тысяч из них либо написаны на TS, либо имеют выделенные типы.
А единой документации по этим типам нет!
Точнее, не было, но теперь вышел https://tsdocs.dev/
Это система поиска по существующим пакетам с типами. Она установит нужный пакет, распарсит типы и JSDoc и отобразит в удобном формате.
К слову, котаны, что вы предпочитаете по cmd- (ctrl)-click в редакторе? Прыгать к имплементации, или к типам?
Я вот — к имплементации, прыгать к типам меня раздражает.
#typescript #dts #types #doc #бородач
#тип дня
Что делать если вам нужно создать тип, параметры которого служат для передачи в библиотечную функцию? Aka тип аргументов не торчит наружу?
Не делайте это ручками, используйте служебный тип Parameters!
Песочница
#typescript #utility
Что делать если вам нужно создать тип, параметры которого служат для передачи в библиотечную функцию? Aka тип аргументов не торчит наружу?
Не делайте это ручками, используйте служебный тип Parameters!
const createPerson = ({
firstName,
lastName
}: {
firstName: string,
lastName: string
}) => ({
firstName,
lastName
})
type CreatePersonParams = Parameters<typeof createPerson>[0];
const params: CreatePersonParams = {
firstName: 'John',
lastName: 'Doe'
};
Песочница
#typescript #utility
www.typescriptlang.org
Documentation - Utility Types
Types which are globally included in TypeScript
#тип дня
Четыре ночи провёл в деревне в глубинной Финляндии и возвращаться в привычный режим очень и очень тяжело.
Прыжки со скалы просто так не проходят.
Здесь отмечают день солнцестояния. Официальный выходной, плюс многие компании добавляют ещё один день — канун. Из города уезжают вообще все, пустота.
В общем, тип дня от Кори Хауса: как указать TypeScript, что поле принимает любое строковое значение, но при этом получить автоподсказку для наиболее часто используемых из них?
Очень просто:
Результат на иллюстрации. Песочница.
Объединение с пустым типом предотвращает попытки языкового сервера от приведения типа к строке.
На самом деле это равнозначно следующему выражению, более понятному:
Пользуемся!
#typescript
Четыре ночи провёл в деревне в глубинной Финляндии и возвращаться в привычный режим очень и очень тяжело.
Прыжки со скалы просто так не проходят.
Здесь отмечают день солнцестояния. Официальный выходной, плюс многие компании добавляют ещё один день — канун. Из города уезжают вообще все, пустота.
В общем, тип дня от Кори Хауса: как указать TypeScript, что поле принимает любое строковое значение, но при этом получить автоподсказку для наиболее часто используемых из них?
Очень просто:
type Status = 'open' | 'closed' | string & {}
Результат на иллюстрации. Песочница.
Объединение с пустым типом предотвращает попытки языкового сервера от приведения типа к строке.
На самом деле это равнозначно следующему выражению, более понятному:
type Status = 'open' | 'closed' | Omit<string, "open" | "closed">
Пользуемся!
#typescript
#новость дня
В node.js появилась экспериментальная нативная поддержка TypeScript!
Крепко же их bun приложил...
Ссылка на PR: https://github.com/nodejs/node/pull/53725
По факту происходит отбрасывание типов, поэтому средства вроде Enum и namespace не поддерживаются. Инициатива предоставления стабильного API поверх TypeScript получила название amaro и в дальнейшем планируется выделение в отдельный обновляемый модуль. Работает (кто бы сомневался) при помощи swc, собранного в WebAssembly!
Так что никаких больше
...и поехали!
#node #typescript #ts
В node.js появилась экспериментальная нативная поддержка TypeScript!
Крепко же их bun приложил...
Ссылка на PR: https://github.com/nodejs/node/pull/53725
По факту происходит отбрасывание типов, поэтому средства вроде Enum и namespace не поддерживаются. Инициатива предоставления стабильного API поверх TypeScript получила название amaro и в дальнейшем планируется выделение в отдельный обновляемый модуль. Работает (кто бы сомневался) при помощи swc, собранного в WebAssembly!
Так что никаких больше
ts-node
!node main.ts
...и поехали!
#node #typescript #ts
GitHub
module: add --experimental-strip-types by marco-ippolito · Pull Request #53725 · nodejs/node
It is possible to execute TypeScript files by setting the experimental flag --experimental-strip-types.
Node.js will transpile TypeScript source code into JavaScript source code.
During the transpi...
Node.js will transpile TypeScript source code into JavaScript source code.
During the transpi...
#расширение дня
Дал слабину и где-то в глубине кода указал
Воспользовался
И при этом не используешь WebStorm?
Есть решение! Расширение для VS Code any-xray от Дана Вандеркама: https://marketplace.visualstudio.com/items?itemName=danvk.any-xray
Про DefinitelyTyped не шутка, всякое бывает: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b0ad06b09bd5547cf6f01a8355cbcb309d3f5e24/types/find-package-json/package-json.d.ts#L449
У React в типах, кстати, тоже.
Это не плохо само по себе, не все хотят заниматься ментальной гимнастикой там, где в целом можно спихнуть проверки на пользователя типов.
Но подсветить такие случаи, чтобы не попасть впросак — удобно.
#vscode #typescript
Дал слабину и где-то в глубине кода указал
any
?Воспользовался
DefinitelyTyped
, не проверив?И при этом не используешь WebStorm?
Есть решение! Расширение для VS Code any-xray от Дана Вандеркама: https://marketplace.visualstudio.com/items?itemName=danvk.any-xray
Про DefinitelyTyped не шутка, всякое бывает: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b0ad06b09bd5547cf6f01a8355cbcb309d3f5e24/types/find-package-json/package-json.d.ts#L449
У React в типах, кстати, тоже.
Это не плохо само по себе, не все хотят заниматься ментальной гимнастикой там, где в целом можно спихнуть проверки на пользователя типов.
Но подсветить такие случаи, чтобы не попасть впросак — удобно.
#vscode #typescript
#инструмент дня
Устал вручную типизировать ответы от API для TypeScript или любого другого типизированного языка?
Есть решение!
https://app.quicktype.io/
Фиганул туда JSON — получил нужную структуру или описание типа, даже с тайпгардами. Уютненько!
Есть расширение для VS Code: https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype
Ещё один мощный инструмент в тему дня: https://transform.tools. Одним типизированием JSON не ограничивается: можно CSS в Tailwind, а можно Flow в TypeScript.
Вот, например, если кто использует Zod — конвертор типов в схему Zod: https://transform.tools/typescript-to-zod
#json #typescript #type #бородач
Устал вручную типизировать ответы от API для TypeScript или любого другого типизированного языка?
Есть решение!
https://app.quicktype.io/
Фиганул туда JSON — получил нужную структуру или описание типа, даже с тайпгардами. Уютненько!
Есть расширение для VS Code: https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype
Ещё один мощный инструмент в тему дня: https://transform.tools. Одним типизированием JSON не ограничивается: можно CSS в Tailwind, а можно Flow в TypeScript.
Вот, например, если кто использует Zod — конвертор типов в схему Zod: https://transform.tools/typescript-to-zod
#json #typescript #type #бородач
Media is too big
VIEW IN TELEGRAM
#новость дня
Вчерашнего дня, конечно, и многие из вас уже в курсе, но...
TypeScript переписывают на Go!
Да, если вы не знали — транслятор TypeScript всё это время был написан на самом себе, что, как вы понимаете, не делало его быстрым :)
И вот, новость: https://devblogs.microsoft.com/typescript/typescript-native-port/
Результат ошеломляет: разбор типов и сборка уже в 10 раз быстрее! Это означает, что и LSP в ваших IDE будут быстрее. И работать станет приятнее.
Очень рекомендую пойти почитать статью.
Кстати, кто же этот седой дядя на видео? А это Андерс Хейлсберг! Создатель Turbo Pascal, Delphi, C# и, внезапно, TypeScript.
И на этом видео он, в том числе, объясняет, почему не Rust. Этим вопросом задолбали уже всю команду.
И, если коротко:
1. Это портирование, а не переписывание. Они хотели оставить структуру проекта и работы над ним той же, что и была.
2. Rust, хоть и облегчает управление памятью, полностью не освобождает от связанного с этим управлением бойлерплейта. И, поскольку, структура транслятора TypeScript представляет из собой огромный набор вложенных друг в друга структур, количество бойлерплейта вышло бы неразумным.
В общем, нас ждёт дивный новый мир! И я очень рад. И выбором языка тоже.
#typescript #go
Вчерашнего дня, конечно, и многие из вас уже в курсе, но...
TypeScript переписывают на Go!
Да, если вы не знали — транслятор TypeScript всё это время был написан на самом себе, что, как вы понимаете, не делало его быстрым :)
И вот, новость: https://devblogs.microsoft.com/typescript/typescript-native-port/
Результат ошеломляет: разбор типов и сборка уже в 10 раз быстрее! Это означает, что и LSP в ваших IDE будут быстрее. И работать станет приятнее.
Очень рекомендую пойти почитать статью.
Кстати, кто же этот седой дядя на видео? А это Андерс Хейлсберг! Создатель Turbo Pascal, Delphi, C# и, внезапно, TypeScript.
И на этом видео он, в том числе, объясняет, почему не Rust. Этим вопросом задолбали уже всю команду.
И, если коротко:
1. Это портирование, а не переписывание. Они хотели оставить структуру проекта и работы над ним той же, что и была.
2. Rust, хоть и облегчает управление памятью, полностью не освобождает от связанного с этим управлением бойлерплейта. И, поскольку, структура транслятора TypeScript представляет из собой огромный набор вложенных друг в друга структур, количество бойлерплейта вышло бы неразумным.
В общем, нас ждёт дивный новый мир! И я очень рад. И выбором языка тоже.
#typescript #go
#баг дня
Как вы думаете, что обозначает тип {}?
Ну, буквально:
Быть может, пустой объект? Да. А может, объект с любыми свойствами? Тоже да. А может, число или строка? И опять, да. А пустые? Да! А может, булево значение? Невероятно, но тоже да!
А может, null или undefined ? Нет. Вот тут — нет. Песочница.
Поэтому смысла в использовании типов {} или Object (второе лишь псевдоним к первому) довольно мало.
Если вам нужен пустой объект — так и пишите, Record<PropertyKey, never>.
Подробнее у Мэтта Покока: https://www.totaltypescript.com/the-empty-object-type-in-typescript.
В чём же баг, спросите вы?
А баг у нас на этот раз в реализации проверки типов в WebStorm/PhpStorm. У JetBrains, короче.
Мы выводим типы из схем Zod, но для целей создания шаблона, мне потребовалось исключить некоторые свойства из проверки:
И мощно получил в лицо: тип ресолвился за 3 минуты на MacBook Pro M2, вешая интерфейс PhpStorm напрочь. Каждый раз.
Решение пришло откуда не ждали:
Обратите внимание на пустой тип. Обнаружил я это случайно: в первом варианте я ещё и добавлял айди шаблона, но впоследствии — отказался.
По всей видимости, система типов IntelliJ построена таким способом, что рассчитвывает конъюнкцию типов как новый тип и кеширует на месте. Но это лишь предположение.
В VS Code, кстати, проблемы не наблюдается.
После обращения в поддержку, мне было рекомендовано включить настройку Use types from server, что буквально выключает встроенные средства и использует типы от LSP. Что, собственно, мне только в плюс.
А как ваши дни проходят? 🙂
#jetbrains #typescript #lsp
Как вы думаете, что обозначает тип {}?
Ну, буквально:
type b = {};
Быть может, пустой объект? Да. А может, объект с любыми свойствами? Тоже да. А может, число или строка? И опять, да. А пустые? Да! А может, булево значение? Невероятно, но тоже да!
А может, null или undefined ? Нет. Вот тут — нет. Песочница.
Поэтому смысла в использовании типов {} или Object (второе лишь псевдоним к первому) довольно мало.
Если вам нужен пустой объект — так и пишите, Record<PropertyKey, never>.
Подробнее у Мэтта Покока: https://www.totaltypescript.com/the-empty-object-type-in-typescript.
В чём же баг, спросите вы?
А баг у нас на этот раз в реализации проверки типов в WebStorm/PhpStorm. У JetBrains, короче.
Мы выводим типы из схем Zod, но для целей создания шаблона, мне потребовалось исключить некоторые свойства из проверки:
TemplateQueryDetails = Omit<
z.infer<typeof QueryDetails>, 'metadata'
>;
И мощно получил в лицо: тип ресолвился за 3 минуты на MacBook Pro M2, вешая интерфейс PhpStorm напрочь. Каждый раз.
Решение пришло откуда не ждали:
TemplateQueryDetails = Omit<
z.infer<typeof QueryDetails>, 'metadata'
> & {};
Обратите внимание на пустой тип. Обнаружил я это случайно: в первом варианте я ещё и добавлял айди шаблона, но впоследствии — отказался.
По всей видимости, система типов IntelliJ построена таким способом, что рассчитвывает конъюнкцию типов как новый тип и кеширует на месте. Но это лишь предположение.
В VS Code, кстати, проблемы не наблюдается.
После обращения в поддержку, мне было рекомендовано включить настройку Use types from server, что буквально выключает встроенные средства и использует типы от LSP. Что, собственно, мне только в плюс.
А как ваши дни проходят? 🙂
#jetbrains #typescript #lsp