はじめに
開発中、配列の型の定義をしていてタプル型になっていたため意図した挙動が得られませんでした。
そもそもタプル型についての知見が乏しかったため、これを機会にまとめたものを共有させていただきます。
そもそもタプル型とは?
1番こちらの記事の説明がしっくりきました。
https://qiita.com/suyamatatsuya/items/8c256036020f99f983da
特定の数と型の順序が決まっているもの。
type tupleCompulsion = [
string,
number
]
こちらの型を使う場合stringとnumberの順番を守って値を入れないとエラーになります。
今回私が使っていたもの
type arrTupleLabelled = {
nameAge: [
{
name: string;
age: number;
}
];
};
こちらのような型を使って値を代入する場合、通常は1つのデータしか入れることができないため下記のように型の明示のあとに[]の記述が必要になります。
const arrTupleLabelledData2: arrTupleLabelled[] = [
{ nameAge: [{ name: "たろう", age: 35 }] },
{ nameAge: [{ name: "じろう", age: 30 }] },
{ nameAge: [{ name: "さぶろう", age: 25 }] },
];
以後、メンテナンスで混乱が生じそうだったため一般的な型の記述へ修正しました。
type arrLabelled = {
nameAge: {
name: string;
age: number;
}[];
};
しかしタプル型について調べていくと、順番を強制、数を強制することができるため使い方によっては不要なバグを減らすこともできるのでは?と思いました。
まとめコード
// ➀ 一般的な配列の型 複数のデータ許容
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>
))
))}
</>
);
}
参考
おわりに
タプル型使いにくそう・・・と初見は思いましたが、調べていくと可能性も見えました。
今後、チャンスがあれば使ってみようと思います。
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!
▼▼▼