Вывод типа аргумента многомерного массива - PullRequest
0 голосов
/ 12 июня 2019

При передаче универсального многомерного массива T [] [] (или остальных параметров T []) создается впечатление, что typcript ожидает, что тип массивов, следующих за первым массивом, будет надмножеством первых типов массивов.

function abc<T>(values: T[][]): T[] {
    return values[0];
}

abc([[1], ['string'], [2], [3]]) // Error: Type 'string' is not assignable to type 'number'.

Почему это?и я могу заставить его выводить тип как (число | строка) [] []?

Ответы [ 2 ]

0 голосов
/ 14 июня 2019

Итак, наконец, я выяснил, как заставить эту работу работать.

Если вы указываете многомерный массив как универсальный тип, он работает, как и ожидалось:

function abc<T, TMultiArray extends T[][]>(arr: TMultiArray): T[] {
    // Pseudo logic that returns any of the values
    return arr[Math.floor(Math.random() * arr.length)];
}

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

abc([[1], ['string']])

И это дает ошибку, как и ожидалось

const y: number[] = abc([[2], ['string']]) // Type 'string' is not assignable to type 'number'.
0 голосов
/ 12 июня 2019

Почему бы не дать намек, что вы хотите, чтобы это был тип объединения?

abc<string | number>([[1], ['string'], [2], [3]])

В вашем случае выдает ошибку, поскольку TS предполагает, что вы хотите, чтобы T был единичным типом, а не типом объединения.

Представьте, что TS всегда соглашался с любыми типами, которые вы помещаете в массив, и просто расширял тип, чтобы соответствовать ему. Вы потеряете все преимущества проверки типов и, возможно, в итоге получите string | number | boolean | etc тип объединения, который по существу эквивалентен any и вряд ли будет тем, что вы намеревались.

...