TypeScript - Tuple(튜플)

DatQueue·2022년 9월 6일
4
post-thumbnail

타입스크립트에는 자바스크립트엔 없는 굉장히(?) 유용한 타입인 “튜플”이 존재한다.

이번 페이지에선 이 “튜플”의 구조 및 특징과 어떠한 장점으로써 쓰이는지 알아보고자 한다. 더욱이 “타입스크립트”에선 해당 “튜플”을 어떻게 다루는지를 중점적으로 파헤쳐보자.

Tuple의 사전적 의미

튜플(tuple)은 셀 수 있는 수량의 순서 있는 열거이다.

위의 문장은 프로그래밍 개념으로써의 튜플의 정의가 아닌 포괄적 “튜플”이란 단어의 정의이다.

프로그래밍 측면에서도 위의 정의를 근거하여 나타낼 수 있다.

타입스크립트의 Tuple

> Typed Arrays (타입 배열)

타입스크립트에서 “Tuple”은 아래와 같이 정의한다.

A tuple is a typed array with a pre-defined length and types for each index.

해석해보자면 “튜플은 길이와 각 요소마다의 타입이 고정된 배열이다 ” 정도가 된다.

> 튜플의 작성법

To define a tuple, specify the type of each element in the array

ex )

// define our tuple
let myTuple : [number , boolean , string];

// initialize correctly
myTuple = [123 , true , "tuple is good!"];

만약 튜플을 정의하였을때 해당 배열의 타입 요소 순서가 아닌 임의의 순서로 값을 담아주면 어떻게 될까? 아래와 같이 말이다.

myTuple = [ture , "tuple is good!" , 123]; // --> initialize incorrectly

에러를 띄우게 된다.

튜플로 지정한 배열의 요소들은 순서또한 고정되어야 함을 말한다.

> 튜플은 왜 필요할까? (튜플의 장점)

예시를 통해 알아보자.

VIP 유저에게 생일일 경우 축하 알림 및 쿠폰을 주는 이벤트를 실시하고자 한다. 그러기 위해선 우린 먼저 유저의 고유 정보 및 생일날짜, 그리고 VIP 회원인지와 같은 정보를 조회하여야 한다.

아래와 같이 배열의 첫 번째 요소는 유저의 고유 인덱스 , 두 번째 요소는 아이디 , 세 번째 요소는 패스워드 , 네 번째 요소는 생일날짜가 기입되는 userInfo라는 배열이 존재한다 가정하자.

const userInfo1 = [1, 'user1@example.com' , 'abcd123' , '1999-01-01' , true];

그리고 해당 규칙으로 동일하게 다른 사용자들의 정보 또한 변수에 담고 있다고 가정하자.

const userInfo1 = [1, 'user1@example.com' , 'abcd123' , '1999-01-01' , true];
const userInfo2 = [2, 'user2@example.com' , 'abcd1234' , '1994-05-12' , false];
const userInfo3 = [3, 'user3@example.com' , 'abcd12345' , '2001-03-15' , false];

그런데 만약, 이 규칙을 모르는 어떠한 개발자가 아이디와 고유 인덱스, 혹은 생년월일과 VIP 여부 요소부분 순서를 바꿔서 배열을 만들면 어떻게 될까? 기존의 배열 순서를 무시하는 것이다.

const userInfo4 = ['user4@example.com', 4 , true , '2002-10-25' , 'abcd123456']; // 순서 무시

아마 분명히 오류가 발생할 것이다.

이러한 문제를 해결하기 위해 우리는 타입스크립트에서 “튜플”을 이용하는 것이다.

type UserInfo = [number , string, string ,string , boolean];  // tuple 타입 정의

// initialize correctly
const userInfo1 : UserInfo = [1, 'user1@example.com' , 'abcd123' , '1999-01-01' , true];
const userInfo2 : UserInfo = [2, 'user2@example.com' , 'abcd1234' , '1994-05-12' , false];
const userInfo3 : UserInfo = [3, 'user3@example.com' , 'abcd12345' , '2001-03-15' , false];

// initialize incorrectly
const userInfo4 : UserInfo = ['user4@example.com', 4 , true , '2002-10-25' , 'abcd123456']; // Error

선언한 튜플 타입 UserInfo 배열의 각 인덱스 순서와 다르게 작성하였을 경우 (userInfo4) 에러를 띄우게 된다.

> 튜플의 맹점과 그 해결법 (Readonly)

튜플엔 한 가지 이 존재한다. 배열에 요소를 추가할 때 쓰이는 메서드인 push를 사용하면 기존의 튜플 타입을 따른다고 선언함에도 불구하고 문제없이 배열의 길이가 늘어나게 된다.

type UserInfo = [number , string , string , string , boolean];

let userInfo1 : UserInfo = [1, 'user1@example.com' , 'abcd123' , '1999-01-01' , true];

userInfo1.push('hello'); // push로 string 타입인 'hello' 추가

console.log(userInfo1); // (6) [1, 'user1@example.com', 'abcd123', '1999-01-01', true, 'hello']

push를 통해 요소를 추가 시 배열의 가장 마지막 요소로 오게 되고, 결국 타입의 순서는 바뀌지 않으므로 큰 문제가 되지 않을 것이라 생각 할 수 있다.

그렇지만 이는 우리가 원했던 “튜플”이란 기능의 목적과 달라지게 된다.

우리는 배열 인덱스마다의 타입과 순서를 “완벽히” 고정시키기 위해 **readonly**키워드를 사용할 수 있다.

작성법은 위의 예시를 통해 적용시켜 보자.

type UserInfo = readonly [number , string, string ,string , boolean]; // 배열 앞에 readonly 적용

let userInfo1 : UserInfo = [1, 'user1@example.com' , 'abcd123' , '1999-01-01' , true];

userInfo1.push('hello'); // Error

튜플 타입을 선언하는 과정에 있어 배열 앞에 **readonly**키워드를 추가해줌으로써 작성할 수 있다.

다음과 같이 UserInfo라는 튜플 타입을 따르는 userInfo1push를 사용할 시 , 컴파일러에선 에러를 발생시키게 된다.

pushUserInfo라는 타입에 존재하지 않는다고 알려준다.

> Named Tuples

Named tuples allow us to provide context for our values at each index.

“Named tuples” 는 각 인덱스마다의 값에 관한 정보를 제공하도록 해준다.

const graph : [x : number , y : number] = [12.3 , 32.1];
const graph : [x : number , y : number , pointName : string] = [12.3 , 32.1 , "A"];

> Destructuring Tuples

Since tuples are arrays we can also destructure them.

“튜플”은 “배열”이므로 구조 분해를 할 수 있다.

const graph : [number , number] = [12.3 , 32.1];

// Destructuring Tuples
const [x , y] = graph;  

console.log(x);  // 12.3
console.log(y);  // 32.1

구조 분해 할당 (자바스크립트)에 관해 더 많이 알고 싶다면

⬇⬇⬇
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

생각정리

이렇게 타입스크립트에서 "튜플"이란 개념이 어떻게 작성되고 , 또 어떻게 쓰이는지에 관해 중요한 키워드를 통해 알아보았다. 그냥 이러한 키워드가 있구나 정도로 생각하기 보단 왜 이러한 "튜플"이 등장하였는지에 대해 기존 자바스크립트의 한계와 연관지어 생각해보는것이 중요하다고 본다.

다음 페이지에선 타입스크립트 버전 업그레이드에 따른 조금 더 심화적이면서 복잡한 "튜플"에 관해 알아보고자 한다. 그럼 다음 페이지로 넘어가 보자.

profile
You better cool it off before you burn it out / 티스토리(Kotlin, Android): https://nemoo-dev.tistory.com

0개의 댓글