• Вичерпні масиви в Typescript та їхня роль для розробників

    Прикольний підхід, мені подобається,

    але все одно ж у вас direction буде типізовано як ltr | rtl
    і знову ж таки id мов ви би також типізували як union допустимих значень — мапінг нікуди не дівається де-факто

    при цьому знову ж таки, мені в різних UI можуть бути потрібні різні варіанти тайтлов, і більш того — інший порядок мов, то мені все одно доведеться використовувати мапінг

    Мапінг — це лише окремий випадок чистої функції. Я не вважаю справедливим та коректним вважати цілу підмножину функцій «безглуздим рішенням» та «антіпатерном»

    Підтримав: Dmytro
  • Вичерпні масиви в Typescript та їхня роль для розробників

    для створення API

    наприклад ви хочете створити route loader для ReactRouter

    і у вас таке api:

    createBreadcrumbRouteLoader = (route: R, params: InferredRouteParams) => Promise

    в рантаймі React Router буде в парамс класти значення path params, але по замовчуванню ви не отримуєте автокомпліт, бо params будуть Record, а цей тип дозволить отримувати type safety + приємний автокомпліт

    Можна обійтись без цього, зробивши прямий assertion params, але знову ж таки — це не значить що InferredPathParams «бєсполєзний».

    Ще раз: коли ви хочете створити ± просте та приємне API, щоб правильно описати його типо виведення потрібно буде трохи напрягтись і базовим TS тут не обійтись

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Ви б так і почали з того, що ви просто не любите TS і заощадили кучу б часу мені)

    Підтримав: Khrystyna Savchuk
  • Вичерпні масиви в Typescript та їхня роль для розробників

    В статті прямо сказано, що до EnumArray немає вимоги до унікальності і пояснено чому

    І це жодним чином не ставіть цінність самої статті під питання, адже стаття має за мету створити ExhaustiveArray 2-го порядку і вона це робить) Навпаки завдяки цій статті ми можемо ставити тепер питання: «а яка практична цінність цього типу, якщо *аргументи*», але це не впливає на цінність статті)

    Підтримав: Олексій Біляченко
  • Вичерпні масиви в Typescript та їхня роль для розробників

    Ви не відповілі на запитання:

    є задача: визначити порядок письма в програмі

    моє рішення: рішенням цієї задачі є чиста функція (lang: Language) => RTL | LTR

    ви кажете, що «Language» писати не можна. Відповідно яке ваше рішення?
    ви знаєте таку функцію: () => RTL | LTR? чи я маю написати (lang: string) => ...?

    Називати «будь-яку декларацію enum-у» в коді (а відповідно і enum-и як концпецію) антипатерн — це принаймні дуже екстравагантне твердження, а на ділі — неправдиве

    Правда в тому, що enum-и не завжди потрібні і не завжди використовуються за призначенням, але казати що enum як концепція це антипатерн — це не правда

  • Вичерпні масиви в Typescript та їхня роль для розробників

    а стосовно функціонального програмування дуже просто:

    розуміння того, що в функціональному програмуванні циклічні алгоритми реалізується за допомогою рекурсії допоможе зрозуміти, що в TS без рекурсивних типів не можна жити. Відповідно це допоможе відійти від справедливого патерну мислення в «традиційному» програмуванні, що «рекурсивні функції краще уникати без необхідности», і прийняти те, в TS типах рекурсія — це обовʼязкова база

    Також розуміння концепції чистоти функцій допомогає вам зрозуміти, що ви можете цю функцію повністю на типах написати, адже результати чистих функцій можна статично передбачити, так само як і типи TS статично обчислюються:
    наприклад уявимо функцію inferPathParams(route: string) => string[], яка примає рядок в якому записані path параметри: /myRoute/:id/myMusic/:songName/etc/etc2 а повертає масив [«id», «songName»]. Ця функція є чистою, відповідно можна спробувати написати тип InferredPathParams, який буде робити те ж саме але на рівні типів

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Давайте так: теорія множин для будь-якого розуміння TS не потрібна якщо і тільки «якщо представляти типи як множини, то жодне з положень теорії множин не можна буде застосувати до цих множин»; відповідно, «якщо представити типи як множини, і є хоча б одно положення теорії множин яке можна буде застосувати до цих множин, то теорія множин є потрібною для розуміння TS». Забавно, що щоб скласти ці 2 твердження, також потрібно розуміння кванторів з теорії множин)

    Якщо ставитись до типів як до множин, то можна побачити, що багато положень застосовані і до типів:
    1. Концепція union-типів
    2. Концепція intersection-типів
    3. Концепція привласнень на поняттях під множина та супер множина
    4. Концепція never як пустої множини
    5. unknown як універсум
    Можна побачити і місця, де типи проявляють себе складніше або відмінно від множин: наприклад string & number це never, хоча строго кажучи, і там і там є метод toString, тому строго до теорії множин логічно очікувати принаймні {toString: () => string}, а в TS це не так
    Проте навіть в тих місцях, де TS типи розходяться з теорією множин, все одно цікаво їх порівнювати: в чому саме розбіжність і чому розробники TS вирішили так

    Ще раз: тезіс «типи в TS це множини з алгебри» — хибний, проте тезіс «якщо я буду ставитись до типів як до множин, то теорія множин мені зовсім ніяк не зможе допомогти» також хибний — зможе допомогти)

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Дякую за відгук!

    Особисто я в якості головної цінності цієї статті бачу наступне:
    1. Ця стаття дуже гармонійно та природньо поєднує між собою зовсім різні та складні/просунуті TS концепції
    2. Дуже добре демонструє глибину та комплексність мови TS, що має, на мою думку, великий популяризаторський ефект технології
    3. Ця стаття дуже добре демонструє роботу принципу «що іноді щоб вирішити дуже просту (на рівні формулювання) задачу необхідно зануритись та дійти до занадто абстрактних абстракцій» — що правда про Тайпскрипт

    Питання про практичну цінність залишається відкритим, в статті не має заклику негайно пушити цей код собі в проєкти. 100% можу сказати, що створити повноцінний ExhaustiveArray неможливо в загальному випадку. Як альтернативу можна розглядати покриття тестами на рівні типів або навіть поєднати ці 2 підходи

    Підтримав: Oleksandr P
  • Вичерпні масиви в Typescript та їхня роль для розробників

    не зрозумів проблеми: цей фрагмент і має компілюватись

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Ніде не написав, що типи в тс є множинами) Написав, що для розуміння TS необхідні принаймні базові знання теорії множин. Те ж саме і про функціональне програмування: ніде не сказав, що TS додав нові інструменти для функціонального програмування в JS. Сказав, що для глибшого розуміння TS знання теорії функціонального програмування є обовʼязковим). Хоча навіть тезис про те, що TS нічого нового для ФП не приніс це також дискусійно, адже можливості тайпскрипта та його переваги розкриваються на повну саме тоді, коли пишеш код в функціональному стилі, відповідно можна справедливо казати, що ТS мотивує та заохочує розробника писати саме в такому стилі

  • Вичерпні масиви в Typescript та їхня роль для розробників

    «Його декларація в коді» — це і значить що сам enum є аніпатерн, бо що ще можна робити з enum-ами, окрім як їх декларувати? Хіба що дивитись на них в чужому коді)

    І я так і не зрозумів — як мені визначити напрямок письма *не* знаючи мови? Це ж проста чиста функція: мова => напрямок письма?

  • Вичерпні масиви в Typescript та їхня роль для розробників

    до кінця не зрозуміло, що саме є обʼєктом критики: те, що це саме нативний тайпскриптовий enum, чи сам факт використання якогось обʼєкту за своєю семантикою виконуючого функції enum-у

    якщо перший поїнт, то я можу сказати наступне: замінить enum на const obj = {...} as const — валідність сказаного в статті не зміниться. Більше того, ви можете взагалі відмовитись від рантайм сутностей і тримати все на тайп левелі в union-і: type Language = ... | ... | ...; по аналогії з EnumArray можна дуже легко створити UnionArray, який працює так само, лише відрізняється спосіб опису вхідних даних: в EnumArray це літерал обʼєкту, а в UnionArray літерал union-у

    якщо другий поїнт, то це щось цікаве) Я ніколи не чув, що enum-и та їх аналоги як концепція це антипатерн) Розкажіть будь-ласка про альтернативи тоді, і як за допомогою цих альтернатив мені створити union з назвами пород поняшек:
    type PonyBreed = 'Pegassus' | 'Unicorn' | 'Alicorn' | 'Megacorn' | 'Ponycorn'<code>

    Підтримав: Артур Шевченко
  • Вичерпні масиви в Typescript та їхня роль для розробників

    Стосовно другого поїнту, що рішення в статті не підходіть, оскільки не перевіряє на дублікати -
    в статті у висновках покрите це питання: в статті розглядається розробка так званого вичерпного масиву «2-го» порядку, і окремо сказано, що створити повноцінний загальний тип вичерпного масиву «3-го» порядку, який ще і на унікальність перевіряє, неможливо в загальному випадку. Можна лише покрити окремими тестами на унікальність які вертатимуть `false` якщо є дублікати, проте інтегрувати цю перевірку в тип в загальному випадку без факторіальної складності алгоритму ще не вдалось нікому)

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Заважає, що порядок ключів обʼєкта не гарантується при декларації згідно до специфікації і тим паче не гарантується при обході ключів обʼєкту. Той факт, що існують міжбраузерні домовленості про те, як браузери де-факто реалізовують порядок ключів, не є достатнім аргументом покладатись на ці домовленності через низку причин:
    1. по-перше це не фіча, а те, що існує з історичних причин і не прибрано з міркувань зворонтої сумісності
    2. по-друге ці «домовленності» є forgettable, а все що можна забути — це все не type safe
    3. по-третє це просто анти-патерн, бо з коду інша людина та навіть сам автор ніколи не зрозуміє/не згадає з часом «так, а це я впорядковано ключі вказав чи я можу змінювати порядок», якщо не вказати коментар, що також псує якість коду. Будь-який розробник має знати, що якщо він змінить порядок будь-якої властивості в обʼєкті, то код його не зламається і тести не почнуть ломатись
    4. по-четверте ніде нема гарантій, що певний браузер/певне середовище виконання буде дотримуватись цих домовленостей, і що вас код не зламається через це.
    Обʼєкти в JS невпорядковані по своїй природі та згідно до специфікації, відповідно їх не можна використовувати для опису впорядкованих сутностей.

  • Вичерпні масиви в Typescript та їхня роль для розробників

    тим, що ми втрачаємо контроль за можливістю вказувати порядок мов) Навіть у другому варіанті, далі покажу чому

    В першому варіанті здається це очевидно: бо `Object.values` не гарантує ніякого порядку. Також (це вже не стосується теми статті та зовсім з іншого питання), особисто я не за те, щоб на TS enum-ах, викликати Object.values або виконувати над ними інші схожі маніпуляції через саму природу TS enum-ів з купою pitfall-ів та нюансів, про які треба памʼятати, а все, що можна забути — це все не type safe

    В другому варіанті здається все ідеально: тепер у нас source of truth не обʼєкт, а масив з фіксованим порядком. Але це не працює так, бо коли я захочу в 3-х різних компонентах мати різний порядок мов, то мені для кожного потрібно буде створити свій масив з порядком, який нема більше чим типізувати.
    Якщо уважно подивитись в статтю, то можна побачити, що enum Language оголошено в окремому файлі від `languageDisplayNameMap` та `languageOptions`, бо в `languageOptions` вказаний порядок саме для конкретного компоненту `` (і він і оголошений поруч з компонентом), а в компоненті `` в мене може бути інший порядок

    Ви праві в тому, що можна сказати «а в мене буде тільки один селект з одним порядком на весь проєкт» і тоді дійсно другий варіант вирішить проблемо. Але потрібно памʼятати, що це лише окремий випадок, а в загальному випадку це вже не спрацює

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Так пишуть ті, хто розробляє якесь API або бібліотеки, тобто код, кінцевим споживачем якого є розробники, а не продакти, бо тайпскрипт це в також про DX. В повсякденних проєктах, де кінцеві споживачі це люди, дійсно просто важко знайти застосування для складних типоманіпуляцій та типовиведень, але в складних проєктах все одно можна)

    Підтримали: Eugene Rusakov, Serhii, amigo
  • Вичерпні масиви в Typescript та їхня роль для розробників

    Зі свого досвіду роботи та досвіду спілкування з TS розробниками можу зробити наступні тези:

    Ці типи дійсно мʼяко кажучи складніше, ніж наші повсякденні типи, але це тільки на перший погляд. По-перше усі типи тут, окрім самого EnumArray існували та активно використовувались і до цієї статті, особливо тип Intersection (в різних проєктах може називатись по-різному: Intersection, UnionToIntersection, IntersectionFrom, U2I — навіть таку назву зустрічав)

    По-друге, також справедливо зауважити, що такі більш «просунуті» типи рідко зустрічаються саме в повсякденній розробці, бо в більшості нас наша повсякденна розробка спрямована на створення коду, кінцевими споживачами якого будуть звичайні користувачі; проте коли наші кінцеві споживачі — це розробники (тобто коли ми пишемо власну лібу або створюємо якесь ± не саме тривіальне API), то одразу зʼявляється потреба в якихось більш складних інструментах для здійснення нетривіальних маніпуляцій та трансформацій з типами.

    В принципі це проблема Typescript — що щоб створити щось дійсно прикольно потрібно писати напів-езотеричний код та добряче так зануритись в теорію множин та функціональне програмування, але в цьому є і фіча: цей езотеричний код у всіх однаковий і дуже розповсюджений, і коли один раз його розумієш — далі вже можеш його закритими очима створювати. Короче кажучи — ті хто один раз це побачив, запамʼятовують це назовні)

    Конкретно в цій статті немає призову негайно це затягувати в свої кодові бази і ви правильно сказали, що це красива інтелектуальна гімнастика) Мета цієї статті — 1) показати, що тайпскрипт це глибше ніж просто `as any` тa `props: any`; 2) показати, що дуже «складні» на перший погляд речі випливають з дуже простої на перший погляд проблеми

  • Вичерпні масиви в Typescript та їхня роль для розробників

    Замінить перелік мов в коді на перелік пород кошенят) Тематика контенту в enum-у не впливає на зміст статті та на тему статті в цілому

← Сtrl 12 Ctrl →