TGViewer
Khraks dev Khraks dev @khraks_dev · 108 subscribers
Post #20 293
В мире ts достаточно темных зон и иногда выручает только знание нюансов.
Задачка: получить в типо-параметре дженерик функции кортеж его аргумента вот так
const test1 = tuple([1, '2', false]) // [number, string, boolean]


Решаем наивным подходом: Приходит понимание что трактовать аргумент можно двояко — и как гомогенный(одного типа) массив и как кортеж
declare function tupleNaive<T extends ReadonlyArray<any>>(elements: T): T;
tupleWrong([1,'2',false]) // (string | number | boolean)[]
tupleWrong([1, 2]) // number[]
tupleWrong([]) // never[]


Попытка номер 2 (...elements: T) — сигнатура функции поменялась
declare function tupleDisctruction<T extends ReadonlyArray<any>>(...elements: T): T;
tupleDisctruction(1, '2', false) // [number, string, boolean]
tupleDisctruction(1, 2) // [number, number]
tupleDisctruction() // []


Вспоминаю про const для вывода литералов (<const T ...): Почти, но не то
declare function tupleConst<const T extends ReadonlyArray<any>>(elements: T): T;
tupleConst([1, '2', false]) // readonly [1, '2', false]
tupleConst([1, 2]) // readonly [1, 2]
tupleConst([]) // readonly []


Натыкаюсь в исходниках какой-то библиотеки для type-level ts на такой трюк (<T extends ReadonlyArray<any> | readonly [any]>)
declare function tuple<T extends ReadonlyArray<any> | readonly [any]>(elements: T): T;
tuple([1, '2', false]) // [number, string, boolean]
tuple([1, 2]) // [number, number]
tuple([]) // []


Оказывается если в ограничениях типо-аргумента есть хоть один кортеж - то он будет трактоваться как кортеж 🤯
https://github.com/microsoft/TypeScript/issues/27179#issuecomment-422911925
GitHub Add a way to prefer narrowing array to tuple if possible · Issue #27179 · microsoft/TypeScript Search Terms tuple narrow, prefer tuple Suggestion This is a meta-suggestion over the top of some of the cases in #16896 and #26113, basically at current it's quite repetitive to specify overlo...
  • 🔥 4
  • 🤯 2
  • 😱 1
More from @khraks_dev
  1. Sep 10, 2026Добавил еще PR с Context.Mixin, чтобы подмешивать к классу поведение Context.Service Тепер…
  2. Sep 10, 2026Post #56
  3. Sep 7, 2026Post #55
  4. Sep 3, 2026Post #54
  5. Sep 3, 2026Итак HKT на основе TypeLambda interface TypeLambda { readonly Arg1: unknown; readonly Arg2…
  6. Aug 30, 2026# HKT Дефункционализация В TypeScript нет настоящих Higher-Kinded Types (HKT). А они приме…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →