Ах, вам нужны общие значения, как описано в Microsoft / TypeScript # 17574 .Как вы заметили, они не существуют в языке, кроме как в случае универсальных функций.Вы можете указать issue на эту проблему, если хотите, или обсудить свой вариант использования, если считаете, что это полезно.
Учитывая общий интерфейс
interface XYZ<T> {
arr: T[],
dict: Partial<T>
}
Я бы просто использовал этот обходной путь:Создайте обобщенную функцию, чтобы проверить, что значение равно XYZ<T>
для некоторого T
, и разрешить вывод типа для фактического вывода T
всякий раз, когда это необходимо.Никогда не пытайтесь объявлять что-то типа XYZ
.Вот так:
const asXYZ = <T>(xyz: XYZ<T>) => xyz;
const x = asXYZ({
arr: [{ a: 1, b: 2 }, { a: 3, b: 4 }],
dict: { a: 1300 }
}); // becomes XYZ<{a: number, b: number}>
Вышесказанное обычно работает для меня на практике.Плюс в том, что это "естественный" TypeScript.Дело в том, что он не представляет «Мне все равно, какой тип T
» правильно.
Если вы действительно хотите, вы можете определить экзистенциальный тип ,TypeScript изначально не поддерживает их, но есть способ представить это:
interface SomeXYZ {
<R>(processXYZ: <T>(x: XYZ<T>) => R): R
}
const asSomeXYZ = <T>(xyz: XYZ<T>): SomeXYZ =>
<R>(processXYZ: <T>(x: XYZ<T>) => R) => processXYZ(xyz);
Тип SomeXYZ
- это конкретный тип, который больше не заботится о T
, но содержит ссылкуXYZ<T>
для некоторые T. Вы используете asSomeXYZ
для создания объекта из объекта:
const someXYZ: SomeXYZ = asSomeXYZ({
arr: [{ a: 1, b: 2 }, { a: 3, b: 4 }],
dict: { a: 1300 }
}); // SomeXYZ
И используете его, передавая функцию, которая обрабатывает удерживаемую ссылку.Эта функция должна быть готова для XYZ<T>
для любого T
, так как вы не знаете, какой тип T
a SomeXYZ
удерживает.
// use one
const xyzArrLength = someXYZ((xyz => xyz.arr.length))
xyzArrLength
являетсяnumber
, поскольку функция xyz => xyz.arr.length
возвращает number
независимо от того, что T
.
Экзистенциальные типы в TypeScript неуклюжи, поскольку происходит много инверсий управления.В этом главный недостаток, и поэтому я обычно использую менее совершенный, но более легкий для размышления обходной путь, который я представил первым.
Надеюсь, что это поможет.Удачи!
РЕДАКТИРОВАТЬ: перечитывание вашего вопроса заставляет меня думать, что вы на самом деле спрашиваете ответ, который я назвал «обходным путем».Так что ... использовать это?Приветствия.