2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TypeScript】タプル型の書き方、展開の仕方まとめ

Posted at

はじめに

開発中、配列の型の定義をしていてタプル型になっていたため意図した挙動が得られませんでした。
そもそもタプル型についての知見が乏しかったため、これを機会にまとめたものを共有させていただきます。

そもそもタプル型とは?

1番こちらの記事の説明がしっくりきました。
https://qiita.com/suyamatatsuya/items/8c256036020f99f983da
特定の数と型の順序が決まっているもの。

.tsx
type tupleCompulsion = [
  string,
  number
]

こちらの型を使う場合stringとnumberの順番を守って値を入れないとエラーになります。

今回私が使っていたもの

.tsx
type arrTupleLabelled = {
  nameAge: [
    {
      name: string;
      age: number;
    }
  ];
};

こちらのような型を使って値を代入する場合、通常は1つのデータしか入れることができないため下記のように型の明示のあとに[]の記述が必要になります。

.tsx
const arrTupleLabelledData2: arrTupleLabelled[] = [
    { nameAge: [{ name: "たろう", age: 35 }] },
    { nameAge: [{ name: "じろう", age: 30 }] },
    { nameAge: [{ name: "さぶろう", age: 25 }] },
  ];

以後、メンテナンスで混乱が生じそうだったため一般的な型の記述へ修正しました。

.tsx
type arrLabelled = {
  nameAge: {
    name: string;
    age: number;
  }[];
};

しかしタプル型について調べていくと、順番を強制、数を強制することができるため使い方によっては不要なバグを減らすこともできるのでは?と思いました。

まとめコード

.tsx
// ➀ 一般的な配列の型 複数のデータ許容
type arr = {
  name: string;
  age: number;
}[];

// ➁ キーを設定したラベル付きの一般的な配列の型 複数のデータ許容
type arrLabelled = {
  nameAge: {
    name: string;
    age: number;
  }[];
};


// ➂ 順番強制のタプル型
type tupleCompulsion = [
  string,
  number
]

// ➃ タプル型(キー付き) このままだと複数のデータを許容しない 配列の中にオブジェクトを定義
type arrTuple = [
  {
    name: string;
    age: number;
  }
];

// ➄ ラベル付きのタプル型(キー付き) このままだと複数データ許容しない
type arrTupleLabelled = {
  nameAge: [
    {
      name: string;
      age: number;
    }
  ];
};

export default function App() {

  // ➀ 一般的な配列データ
  const arrData: arr = [
    { name: "たろう", age: 35 },
    { name: "じろう", age: 30 },
    { name: "さぶろう", age: 25 },
  ];

  // ➁ キーを設定したラベル付きの一般的な配列のデータ
  const arrLabelledData: arrLabelled = {
    nameAge: [
      { name: "たろう", age: 35 },
      { name: "じろう", age: 30 },
      { name: "さぶろう", age: 25 },
    ],
  };

  // ➂ タプル型順番強制データ
  // string, number の順番を逆にして代入するとエラーになります
  const tupleCompulsionData1: tupleCompulsion = ["たろう", 35];

  // ➌ タプル型順番強制複数データ許容
  // こちらもstring, number の順番必須です
  const tupleCompulsionData2: tupleCompulsion[] = [
    ["たろう", 35] ,
    ["じろう", 30],
    ["さぶろう", 25]
  ];

  // ➃ タプル型(キー付き)データ1つのデータしか代入できない
  // キーがあるので順序関係ありません
  // このまま複数のデータを代入しようとするとエラーになります
  const arrTupleData1: arrTuple = [{ name: "たろう", age: 35 }] ;

  // ➍ タプル型(キー付き)に対し複数データを許容させたもの
  const arrTupleData2: arrTuple[] = [
    [{ name: "たろう", age: 35 }],
    [{ name: "じろう", age: 30 }],
    [{ name: "さぶろう", age: 25 }],
  ];

  // ➄ラベル付きタプル型データ(キー付き)1つのデータしか代入できない
  const arrTupleLabelledData1: arrTupleLabelled = {
    nameAge: [
      {
        name: "たろう",
        age: 35,
      },
    ],
  };

  // ➎ ラベル付きタプル型(キー付き)複数データ許容
  const arrTupleLabelledData2: arrTupleLabelled[] = [
    { nameAge: [{ name: "たろう", age: 35 }] },
    { nameAge: [{ name: "じろう", age: 30 }] },
    { nameAge: [{ name: "さぶろう", age: 25 }] },
  ];

  return (
    <>
    {/* 上記データを展開してみる */}
      <h3>➀ 一般的な配列データ</h3>
      {arrData.map((item, index) => (
        <ul key={index}>
          <li>
            {item.name}-{item.age}
          </li>
        </ul>
      ))}

      <h3>➁ ラベル付きの一般的な配列データ</h3>
      {arrLabelledData.nameAge.map((item, index) => (
        <ul key={index}>
          <li>
            {item.name}-{item.age}
          </li>
        </ul>
      ))}

      <h3>➂ タプル型順番強制データ</h3>
      <li>{tupleCompulsionData1[0]} - {tupleCompulsionData1[1]}</li>

      <h3>➌ タプル型順番強制複数データ許容</h3>
      {tupleCompulsionData2.map((item, index) => (
        <ul key={index}>
          <li>{item[0]} - {item[1]}</li>
        </ul>
      ))}

      <h3>➃ タプル型(キー付き)データ1つのデータしか代入できない</h3>
      {arrTupleData1.map((item, index) => (
        <ul key={index}>
          <li>
            {item.name} - {item.age}
          </li>
        </ul>
      ))}

      <h3>➍ タプル型(キー付き)に対し複数データを許容させたもの</h3>
      {arrTupleData2.map((tuple, tupleIndex) =>
        tuple.map((item, index) => (
          <ul key={`${tupleIndex}${index}`}>
            <li>
              {item.name} - {item.age}
            </li>
          </ul>
        ))
      )}

      <h3>➄ ラベル付きタプル型データ(キー付き)1つのデータしか代入できない</h3>
      {arrTupleLabelledData1.nameAge.map((item, index) => (
        <ul key={index}>
          <li>
            {item.name} - {item.age}
          </li>
        </ul>
      ))}

      <h3>➎ ラベル付きタプル型(キー付き)複数データ許容</h3>
      {arrTupleLabelledData2.map((tuplisLabelled, tuplisLabelledIndex) => (
        tuplisLabelled.nameAge.map((item, index) => (
          <ul key={`${tuplisLabelledIndex}${index}`}>
            <li>{item.name} - {item.age}</li>
          </ul>
        ))
      ))}
    </>
  );
}

タプル型まとめコード表示.png

参考

おわりに

タプル型使いにくそう・・・と初見は思いましたが、調べていくと可能性も見えました。
今後、チャンスがあれば使ってみようと思います。

JISOUのメンバー募集中!

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!
▼▼▼

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?