#typescript
Вопрос:
Я хочу описать некоторые данные, как если бы значение в массиве могло быть другим массивом чисел, это делается бесконечно, поэтому типы должны быть рекурсивными.
Со следующим кодом я получаю сообщение об ошибке
Type 'number' is not assignable to type 'Data'
type Data = ReadonlyArray<number> | Data[];
const data: Data = [1, 2, 3, [4, 5, [6, 7]]];
Как это исправить, используя последнюю версию машинописного текста?
Ответ №1:
Typescript очень по-разному трактует типы объединений массива и объединения массива. Что — то вроде [1, 2, 3, [4, 5]]
на самом деле имеет тип (number | number[])[]
, которому нельзя присвоить number[] | number[][]
.
Это означает, что вам нужен массив союзов, в котором союз может ссылаться на себя по кругу.
type Data = readonly (number | Data)[];
Выше будет объявлен массив рекурсивного атома только для чтения, number
. Теперь вы сможете назначить [1, 2, 3, [4, 5, [6, 7]]]
Попробуйте это на игровой площадке
Комментарии:
1. а как насчет этого
type Data = ReadonlyArray<number | Data>;
? Что СЛУЧИЛОСЬ?2. в чем разница между readonly и ReadonlyArray здесь? они должны быть эквивалентны, нет?
3. @Radex
readonly number[]
— это то жеReadonlyArray<number>
readonly
самое, что-поскольку ключевое слово просто более общее, вы можете использоватьReadonlyArray<number | Data>
его просто отлично.
Ответ №2:
type E = number
type ListOfE = E[]
type NestedListOfE = (E | NestedListOfE)[]
const a: E = 10
const b: ListOfE = [ 1, 2, 3 ]
const c: NestedListOfE = [ 1, 2, [ 3, [ 4, 5 ] ] ]
Примечание. использование рекурсивных типов доступно только начиная с TS 3.7.