Кто-нибудь знает, как заставить компилятор автоматически определять тип кортежа?
// Now: (string | number)[]
// Wanted: [string, number][]
const x = [ ["a", 2], ["b", 2] ];
Кто-нибудь знает, как заставить компилятор автоматически определять тип кортежа?
// Now: (string | number)[]
// Wanted: [string, number][]
const x = [ ["a", 2], ["b", 2] ];
Это можно сделать, если мы воспользуемся дополнительной функцией, чтобы немного облегчить вывод типов:
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 элементов в кортеже.
Компилятор этого не делает, и нет никакого способа заставить его "знать" это. единственное, что вы можете (и должны делать), - это определить интерфейс, расширяющий массив. нравится:
interface NumStrTuple extends Array<string | number> {
0: number;
1: string;
length: 2;
}
И используйте его, чтобы определить свой const
следующим образом:
const x: NumStrTuple = [ ["a", 2], ["b", 2] ];
type NumStrTuple = [number, string]
- person Aluan Haddad; 21.02.2018
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