Вывести тип кортежа вместо типа объединения

Кто-нибудь знает, как заставить компилятор автоматически определять тип кортежа?

// Now: (string | number)[]
// Wanted: [string, number][]
const x = [ ["a", 2], ["b", 2] ];

person NN_    schedule 19.02.2018    source источник
comment
не похоже, что может, он не может предполагать, что внутренние массивы всегда будут одинаковой длины. Вы должны указать это сами   -  person toskv    schedule 19.02.2018


Ответы (3)


Это можно сделать, если мы воспользуемся дополнительной функцией, чтобы немного облегчить вывод типов:

function tupleArray<T1, T2, T3>(arr:[T1, T2, T3][]) : typeof arr 
function tupleArray<T1, T2>(arr:[T1, T2][]) : typeof arr 
function tupleArray<T1>(arr:[T1][]) : typeof arr 
function tupleArray(arr:any[]) : any[]{
    return arr;
}

var t = tupleArray([ ["a", 2], ["b", 2] ]) // [string, number][]

Изменить

Лучшая версия с меньшим количеством переопределений:

const tupleArray = <T extends ([any] | any[])[]>(args: T): T => args
tupleArray([["A", 1], ["B", 2]]) // [string, number][]

Вы можете добавить больше перегрузок, если вам нужно более 3 элементов в кортеже.

person Titian Cernicova-Dragomir    schedule 19.02.2018

Компилятор этого не делает, и нет никакого способа заставить его "знать" это. единственное, что вы можете (и должны делать), - это определить интерфейс, расширяющий массив. нравится:

interface NumStrTuple extends Array<string | number> {
    0: number;
    1: string;
    length: 2;
}

И используйте его, чтобы определить свой const следующим образом:

const x: NumStrTuple = [ ["a", 2], ["b", 2] ];
person gilamran    schedule 19.02.2018
comment
Это правда, но этот интерфейс бессмысленен, так как вы можете написать type NumStrTuple = [number, string] - person Aluan Haddad; 21.02.2018
comment
Поле length указывает, что массив должен содержать 2 элемента. - person gilamran; 21.02.2018

Теперь вы можете использовать недавно добавленный as const для достижения этой цели:

const x = [ ["a", 2], ["b", 2] ] as const;
// Type is
// readonly [readonly ["a", 2], readonly ["b", 2]]

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions

person jmathew    schedule 21.07.2021