튜플은 타입스크립트에만 존재하는 개념이다.
let members: string[] = ['태연', '윤아', '티파니'];
members는 string 값으로만 구성된 배열이다. 어떤 값들이 있는지 어떤 순서로 되어있는지는 알 수가 없다.
let numAndStrTuple: [number, string] = [1, '3'];
let numAndStrTuple: [number, string] =['1', '3'] // X
하지만 튜플을 사용하게 되면 어떤 값이 있어야 하고, 어떤 순서여야 하는지에 대한 타입을 선언할 수 있다. 조금이라도 다르다면 에러가 발생한다.
numAndStrTuple.push('성시경');
console.log(numAndStrTuple); // [ 1, '3', '성시경' ]
튜플의 흠이라고 한다면 값을 넣었을 때 런타임에서 정상적으로 값이 들어가게 된다. 그래서 이런 상황을 방지하기 위해 readonly 키워드를 사용한다.
let readOnlyTuple: readonly [number, string] = [1, '2'];
readOnlyTuple.push() // error
readonly 키워드를 사용하면 해당 변수의 수정이 불가능하게 된다. 그래서 위의 문제를 해결할 수 있다.
let singers = ['태연', '성시경', '박효신']; // 이걸 튜플로 강제로 만들고 싶다면?
let singersTuple = ['태연', '성시경', '박효신'] as const; // 캐스팅을 하면 된다
const singersTuple2 = ['태연', '성시경', '박효신'] as const; // const로 선언해도 마찬가지다.
let spreadArr: string[] = [...singersTuple, ...singersTuple2, ...['1', '2']];
let nameTuple: [name: string, age: number] = ['태연', 32]; // 차이는 없지만 이름을 넣어서 문맥을 읽기 편함
as const로 캐스팅을 하면 readonly로 변경이 되고, type이 tuple type(['태연', '성시경', '박효신'])으로 변경이 가능해진다.
각각의 타입에 네이밍을 해줄 수 있다. 해당 값이 어떤 값을 의미하는지 문맥적으로 조금 더 읽기 편하다.
let nameTuple: [name: string, age: number] = ['태연', 32];
튜플에 튜플을 할당하려면 기본적으로 같은 타입의 튜플끼리만 가능하다.
const tuple1: [string, string] = ['아이유', '태연'];
const number1: [number, number] = [2, 3];
let tuple3: [boolean, boolean] = tuple1; // X
let tuple4: [number, number, number] = number1 // X
tuple1과 tuple3의 타입이 다르기 때문에 할당이 불가능한 것을 확인할 수 있다.
number1과 tuple4는 number 타입이 들어가는 건 같지만 배열의 인덱스 개수가 다르므로 서로 다른 튜플인 것이다. 따라서 이것 또한 에러가 발생한다.
// tuple과 array의 관계
let mem: [string, string] = ['태연', '윤아'];
let memTuple: string[] = mem; // O
const tuple2: [string, number][] = [
['태연', 32],
['윤아', 23],
['티파니', 30],
];
string으로 구선된 튜플인 mem 변수를 string으로만 구성되어야 하는 타입인 memTuple에 할당은 가능하다. 왜냐면 mem의 변수가 더 자세한 타입이기 때문에 그보다 넓은 범위의 타입을 가진 memTuple에 할당이 가능한 것이다.
반대의 경우는 어떨까?
let mem2: string[] = ['성시경', '박효신'];
let memTuple2: [string, string] = mem2;
좀 더 넓은 범위의 타입을 가진 mem2를 좁은 범위를 가진 타입인 memTuple2에는 할당이 불가능하다.
const tuple2: [string, number][] = [
['태연', 32],
['윤아', 23],
['티파니', 30],
];
튜플을 배우면서 이런 타입은 정확히 어느 상황에서 쓸 수 있을까하는 생각이 든다. 강의를 듣고 나서 추후에 타입스크립트 프로젝트를 진행할 때 이런 궁금증을 해결할 수 있는 상황을 경험해보고 싶다.