Если у вас нет конечного списка возможных типов для T
в ArrayItem<T>
, в TypeScript нет конкретного типа, соответствующего Array<ArrayItem<T>>
. Чтобы представить такую вещь как неуниверсальный тип c, потребуется что-то вроде экзистенциальные типы , которые TypeScript не поддерживает напрямую.
(Если вы do иметь конечный список, например ArrayItem<string> | ArrayItem<number> | ArrayItem<boolean>
, тогда вы можете просто использовать объединение, как в другом ответе.)
Ближе всего к этому можно подойти в TypeScript как общий тип c, и Лучшее, что вы сделаете с точки зрения вывода и предупреждений компилятора, - это представить это как что-то вроде generi c constraint .
Один из способов сделать это - написать generi c вспомогательная функция asMyArray()
принимает кортеж , и компилятор проверяет каждый элемент кортежа, чтобы убедиться, что он соответствует ограничению. Одна загвоздка в том, что {key1: "hi", key2: 2}
соответствует ограничению, если вы разрешаете такие вещи, как string | number
как T
. Чтобы компилятор не принимал все пары типов, я попытаюсь сделать вывод T
только из key1
(см. microsoft / TypeScript # 14829 , чтобы увидеть способы предотвращения вывода из определенного вывода site), а затем просто убедитесь, что key2
соответствует этому:
const asMyArray = <T extends readonly any[]>(
x: { [K in keyof T]: { key1: T[K], key2: T[K] & {} } } | []) =>
x as { [K in keyof T]: { key1: T[K], key2: T[K] } };
Параметр типа generi c T
является кортежем, соответствующим значениям key1
для каждого элемента переданного - в массиве. Переданный массив x
имеет сопоставленный кортеж типа . Бит & {}
снижает приоритет вывода key2
. Бит | []
просто побуждает компилятор вывести кортеж, а не массив (где он не сможет отличить разные элементы друг от друга). Давайте проверим это:
const myArray = asMyArray([{
key1: "hi",
key2: "world"
}, {
key1: 1,
key2: 2
}, {
key1: true,
key2: false
}])
// const asMyArray: <[string, number, boolean]>(...)
Вы можете видеть что T
выводится как [string, number, boolean]
. Это выполняется успешно, в то время как следующее, в котором T
выводится таким же образом, терпит неудачу:
const badArray = asMyArray([{
key1: "hi", key2: 123 // error!
// -------> ~~~~
// number not assignable to string
}, {
key1: 1, key2: "world" // error!
// ----> ~~~~
// string not assignable to number
}, {
key1: true, key2: false
}]);
Похоже, что вы хотите. Хорошо, надеюсь, что это поможет; удачи!
Детская площадка ссылка на код