Подтвердить что ты не робот

TypeScript: невозможно написать гетерогенные литералы массива

Какой тип утверждает, нужно ли мне это компилировать?

class Foo {}
class Bar {}

var f =
[
    [Foo, [1, 2, 3]],
    [Bar, [7, 8, 9]],
];

Ошибка:

Incompatible types in array literal expression
4b9b3361

Ответ 1

Похоже, что typescript имеет гетерогенные массивы. Итак, поскольку этот вопрос возник первым, когда я искал это, и поскольку он чтобы найти это иначе, вот как этот код можно написать сейчас:

class Foo {}
class Bar {}

var f: [Foo|Bar, number[]][] =
    [[new Foo(), [1, 2, 3]],
     [new Bar(), [7, 8, 9]]];

(Теперь, если это пойдет по типу имитации синтаксиса типа, тип также получит синтаксис [Foo|Bar, [...number]][]...)

Он даже работает с аргументами функции, поэтому это typechecks fine:

function foo([obj,nums]: [Foo|Bar, number[]]) {
  for (let i of nums) console.log(`i = ${i}`);
}

f.forEach(foo);

и крайняя версия:

f.forEach(([obj,nums]: [Foo|Bar, number[]]) => {
  for (let i of nums) console.log(`i = ${i}`); });

Ответ 2

Это будет работать:

class Foo {}
class Bar {}

var f: any[][] = [
    [Foo, [1, 2, 3]],
    [Bar, [7, 8, 9]],
];

Это говорит о том, что у вас есть двумерный массив, значения которого могут быть любыми (Foo, Bar, другие массивы и т.д.). Вы также можете использовать утверждение типа для своих вложенных массивов:

class Foo {}
class Bar {}

var f = [
    [<any>Foo, [1, 2, 3]],
    [<any>Bar, [7, 8, 9]],
];

Наличие одного во внутреннем массиве заставляет компилятор выводить его тип как любой [].

Ответ 3

Как и в случае с Typescript 1.4, вы можете создавать союзы типов. Я смог выполнить это так:

function zip<T, X> (array1: T[], array2: X[]): (T|X)[][] {
    return array1.map(function (v: T, i: number) { return [v, array2[i]]; });
}

Конкретный тип, который вы искали бы в вашем случае, будет:

(Foo|Bar|number[])[][]

Или:

(typeof Foo|typeof Bar|number[])[][]