Typescript: tuple indeksinin türünü beyan etmek?


Bir TypeScript Demeti verildiğinde, örneğin:

const arr = [1, 2] as const;

İndeksleme üzerinde statik tür kontrolleri alıyoruz:

console.log(arr[1]);

iyi, ama

console.log(arr[2]);

hatalar ile:

Uzunluğu '2' olan 'readonly [1, 2]' demet tipinde '2' indeksinde öğe yok. ts (2493)

bu harika.


Bir sabiti, o demetin indeksinin türünde olarak tanımlamak istiyorum, böylece o sabite atanabilecek değer aynı kısıtlamalara uyar (0 | 1).

Bunu denedim:

const index: keyof typeof arr = 2 as const;
console.log(arr[index]);

ama TypeScript herhangi bir hata göstermedi. index'in çok geniş bir number olduğunu düşünüyorum.

Cevap #1

Evet, herhangi bir nedenle, demet (tuple) indeksleri, karşılık gelen sayısal literal tipleri olan 0 ve 1 yerine "0" ve "1" gibi sayısal string literal tiplerdir. Ayrıca bir number indeks imzası da vardır, bu yüzden keyof ["a", "b"] size number | "0" | "1" | ... verir. Bu da sadece keyof kullanmanın herhangi bir sayıyı atamanıza izin vereceği anlamına gelir.

Sayısal literalleri hesaplamak istiyorsanız, en az TypeScript 4.8 ve üstü sürümlerde bunu yapmak için şablon literal türlerini kullanabilirsiniz:

type TupleIndices<T extends readonly any[]> =
    Extract<keyof T, `${number}`> extends `${infer N extends number}` ? N : never;

Önce tam anahtar kümesinden sayısal dize sabiti türlerini `$ {number}` üzerinde filtreleyerek Extract ile çıkarıyorum; bu, sayıya dönüştürülebilen tüm dize kümesini içeriyor. Bu, number türünü (ki bu bir dize değil) ve ayrıca "length", "slice" ve diğer dizi üyelerini elemiş oluyor. Böylece bize "0" | "1" | "2" | ... kalıyor. Daha sonra TypeScript 4.8 ile tanıtılan geliştirilmiş infer türlerini kullanarak bu dize sabitlerini sayısal sabitlere dönüştürüyorum.

Bu size şunu verir:

const arr = [1, 2] as const;

type ArrIndices = TupleIndices<typeof arr>;
// type ArrIndices = 0 | 1

type Also = TupleIndices<[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]>;
// type Also = 0 | 1 | 2 | 9 | 3 | 4 | 5 | 6 | 7 | 8

Koda yönelik oyun alanı bağlantısı

İlgili makaleler