Компилятор TypeScript не будет использовать общее ограничение в качестве позиции вывода.См. этот похожий вопрос GitHub для обсуждения этого вопроса.Это означает, что, хотя t(arr)
приводит к выводу Src
как number[]
, результирующее ограничение number[] extends A[]
не может использоваться для вывода A
.И поскольку ничто другое не может быть использовано для вывода A
, логический вывод завершается неудачно с пустым типом «Я сдаюсь» {}
.
Чтобы исправить это ... вам, вероятно, на самом деле не нужны два типапараметры.Если вы хотите, чтобы A
всегда был типом элемента массива Src
, вы можете просто получить этот тип элемента, выполнив lookup из Src
'* number
-index тип свойства, то есть: Src[number]
вместо A
:
type TTest = <Src extends any[]>(src: Src) => (x: Src[number]) => Src[number]
declare const arr: number[]
declare const t: TTest
t(arr) // const t: <number[]>(src: number[]) => (x: number) => number
Похоже, это работает для меня.Надеюсь, это поможет.Удачи!
ОБНОВЛЕНИЕ
Учитывая ваши новые типы, можно использовать условный тип и infer
, чтобы получить A
из Src
, например:
type AFromSrc<Src extends TInputs<any>> = Src extends TInputs<infer A> ? A : never;
type TTest = <Src extends TInputs<any>>(src: Src) =>
(x: AFromSrc<Src>) => AFromSrc<Src>
Это также должно работать, пока компилятор может выводить A
из TInputs<A>
.Это зависит от того, насколько TInputs<>
достаточно прозрачен для алгоритма вывода.Вы должны проверить, работает ли он для вас.Если нет, возможно, вам придется быть умнее.
Но если он работает , то вы можете использовать следующую, более простую сигнатуру:
type TTest = <A>(src: TInputs<A>) => (x: A) => A
То есть сохранить A
и вычислить Src
от него.Это не включает условных типов, но ожидает, что компилятор сможет вывести A
из значения типа TInputs<A>
.Если это возможно, отлично.Если нет, вам нужно будет использовать первую подпись и пользовательский AFromSrc
, который поможет компилятору определить A
.
Хорошо, еще раз удачи.