Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?
Organization

TypeScript: 配列の長さを宣言する

やりたいこと

const numbers = [1, 2, 4, 5] as const
const foo = ['f', 'o', 'o'] as const


let numbers_len1: Length<typeof numbers> = 4; //OK
let numbers_len2: Length<typeof numbers> = 5; //エラー
let foo_len1: Length<typeof numbers> = 3; //OK
let foo_len2: Length<typeof numbers> = 4; //エラー

となるように,配列の長さを宣言するLength typeを作りたい。

結論

  • 解決法1
type Length<T extends ReadonlyArray<any>> = T['length']
  • 解決法2
type Length<T extends readonly any[]> = T['length']
  • 解決法3
type Length<T extends any> = T extends { length : infer R } ? R : never;

解説

すべてGenericsを使っています。
ジェネリクスに関しては色んな方が分かりやすい記事をあげているのでそちらを参考にしてください。
https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%82%AF%E3%82%B9

解決法1

type Length<T extends ReadonlyArray<any>> = T['length']

ReadonlyArrayという型がTypeScriptに用意されています。

The ReadonlyArray type describes Arrays that can only be read from

function foo(arr: ReadonlyArray<string>) {
  arr.slice(); // okay
  arr.push("hello!"); // error!
}

名前の通り,配列を変更するようなメソッドは使えませんが,今回のようにlengthを取得することはできます。

解決法2

type Length<T extends readonly any[]> = T['length']

解決法1とほぼ同じです。

今回は配列をas constでreadonlyとしているので,
type Length<T extends any[]> = T['length']
とすると以下のエラーが発生してしまうので注意してください。

The type 'readonly [1, 2, 4, 5]' is 'readonly' and cannot be assigned to the mutable type 'any[]'.

解決法3

type Length<T extends any> = T extends { length : infer R } ? R : never;

inferについてはこちらの記事が分かりやすいです。

T.lengthが存在する場合はそのlengthを返し,存在しない場合はneverを返しています。

補足

TypeChallengeというサイトに問題がたくさん載っていて,その中のLength of Tupleという問題になっています。

上記以外にもたくさん解答があるので参考にしてください。
https://github.com/type-challenges/type-challenges/issues?q=label%3A18+label%3Aanswer

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?