У меня есть надуманное рекурсивное определение кортежа:
type TupleRecursion<T> =
T extends [infer HEAD, ...infer TAIL]
? [HEAD, ...TupleRecursion<TAIL>]
: [];
а затем я пытаюсь ограничить параметры моей функции, используя этот тип. Я ожидаю, что такая функция разрешит любой кортеж:
function foo<T>(tuple: TupleRecursion<T>) {}
Однако когда я вызываю функцию с кортежем с двумя элементами:
test(["test", "hi"]);
Я получаю сообщение об ошибке «Источник имеет 2 элемента, но цель допускает только 0».
Почему это происходит? Как я могу заставить TS принимать кортеж любой длины и правильно определять его тип?
Если имеет значение, почему я это делаю, так это потому, что я действительно хочу TupleRecursion<T> еще больше ограничить кортеж (в частности, обеспечить, чтобы каждый элемент в кортеже удовлетворял сопоставлению предыдущего элемента).






Вы можете изменить тип TupleRecursion для обработки базового случая, когда T — пустой кортеж. Вот обновленная версия типа TupleRecursion:
type TupleRecursion<T> =
T extends [infer HEAD, ...infer TAIL]
? [HEAD, ...TupleRecursion<TAIL>]
: T extends []
? []
: never;
Затем вы можете определить свою функцию foo следующим образом, используя обновленный тип TupleRecursion:
function foo<T extends any[]>(tuple: TupleRecursion<T>) {
// Your function implementation here
}
Хм, я все еще не могу заставить его работать... я что-то упускаю? typescriptlang.org/play/?#code/…
type ConvertRecursiveTuple<T> = T extends [infer One, ...infer Rest]
? Rest extends []
? [One]
: [One, ...ConvertRecursiveTuple<Rest>]
: [];
function foo<T extends any[]>(tuple: T & ConvertRecursiveTuple<T>) {
return tuple;
}
const a = foo(["hello", 123, false]);
Это происходит потому, что TS пытается вывести
Tс помощью обратного сопоставления и неправильно определяет длину. Самый простой способ помешать этому — это обычноT & TupleRecursion<T>, а если вариант использования требует чего-то другого, вы можете попробоватьT extends TupleRecursion<T> ? T : TupleRecursion<T>; оба показаны по ссылке на эту игровую площадку. Это полностью решает вопрос? Если да, то я напишу ответ; если нет, то что мне не хватает?