TypeScript - 배열과 튜플
자바스크립트와 크게 다르지 않은 타입스크립트의 배열, 그리고 그 배열과 정말 유사한 타입스크립트만의 타입인 튜플.
두 타입에 대해서 알아보자.
배열
먼저 배열은 여러 개의 값을 하나의 변수에 담을 수 있는 자료형
let fruits = ["apple", "banana", "orange"];
❶ TS에서의 배열 타입 정의 방법
배열을 정의 하는 방법에는 두가지 방법이 있는데,
// (1) 문자열만 가지는 배열
let fruits: string[] = ['Apple', 'Banana', 'Mango']
// Or (2)
let fruits: Array<string> = ['Apple', 'Banana', 'Mango']
// 숫자만 가지는 배열
let oneToSeven: number[] = [1, 2, 3, 4, 5, 6, 7]
// Or
let oneToSeven: Array<number> = [1, 2, 3, 4, 5, 6, 7]
(1) 배열을 저장하는 변수 이름 뒤에, 콜론(:)을 작성한 다음 배열 요소 타입과 [] 형식으로 배열 타입을 정의 한다.
let numArr: number[] = [1, 2, 3]
(2) Array<배열요소타입> 형태로 배열의 타입을 정의할 수 있다.
let boolArr: Array<boolean> = [true, false, true];
이렇게 꺽쇠와 함께 타입을 작성하는 문법을 타입스크립트의 '제네릭' 이라고 한다.
이 (1)과 (2)의 두 방법은 모두 모양만 다를 뿐 기능은 동일하다. 따라서 특수한 상황이 아닐 경우에는 타이핑이 보다 쉬운 (1)을 사용한다.
❷ 배열의 종류
(1) 혼합 타입 배열 (유니온 타입)
다양한 타입으로 배열 요소를 갖는 배열 타입일 경우,
소괄호와 바(|)를 사용하요 배열 요소가 둘 중 하나의 타입에 해당하도록 하는 방법이 있다.
배열 안에 여러 타입을 허용할 수도 있다.
let array: (string | number)[] = ['Apple', 1, 2, 'Banana', 'Mango', 3]
// Or
let array: Array<string | number> = ['Apple', 1, 2, 'Banana', 'Mango', 3]
해당 타입은 숫자와, 문자의 타입을 동시에 가지는 배열이다.
(2) 객체 타입 배열
배열 안에 객체들이 들어갈 수도 있음
let users: { name: string; age: number }[] = [
{ name: "Jane", age: 25 },
{ name: "Tom", age: 30 }
];
(3) ReadOnly 배열
배열을 읽기 전용으로 만들 수도 있다
readonly 키워드나, ReadonlyArray 타입을 사용하면 된다.
let colors: readonly string[] = ["red", "green", "blue"];
colors.push("yellow"); // 오류! 읽기 전용이니까 수정 불가
let arrA: readonly number[] = [1, 2, 3, 4]
let arrB: ReadonlyArray<number> = [0, 9, 8, 7]
arrA[0] = 123 // Error - TS2542: Index signature in type 'readonly number[]' only permits reading.
arrA.push(123) // Error - TS2339: Property 'push' does not exist on type 'readonly number[]'.
arrB[0] = 123 // Error - TS2542: Index signature in type 'readonly number[]' only permits reading.
arrB.push(123) // Error - TS2339: Property 'push' does not exist on type 'readonly number[]'.
튜플 (Tuple)
튜플은 배열과 매우 유사한, 타입스크립트에만 있는 타입이다.
차이점이라면, 튜플은 ♥︎ 고정된 타입과 ♥︎ 고정된 길이(length)로 타입을 표현 한다.
let tuple: [string, number]
tuple = ['a', 1]
tuple = ['a', 1, 2] // Error - TS2322
tuple = [1, 'a'] // Error - TS2322
다양한 타입으로 정의도 할 수 있다.
let tup2: [number, string, boolean] = [1, "hello", true];
튜플을 사용하는 이유는, 아래 처럼 고정된 타입으로 고정된 배열을 만들 수 있기 때문이다.
→ 순서를 바꿀 경우 자바스크립트에서는 문제가 없는데, 타입 스크립트에서는 오류가 발생되어, 실수를 빠르게 잡을 수 있는 장점이 있다.
// Variables
let userId: number = 1234
let userName: string = 'HEROPY'
let isValid: boolean = true
// Tuple
let user: [number, string, boolean] = [1234, 'HEROPY', true]
console.log(user[0]) // 1234
console.log(user[1]) // 'HEROPY'
console.log(user[2]) // true
const users: [string, number][] = [
["이정환", 1],
["이아무개", 2],
["김아무개", 3],
["박아무개", 4],
[5, "조아무개"], // 오류 발생
];
* 튜플도 결국 배열이다.
튜플은 정해진 타입의 고정된 길이 배열을 표현하지만, 이는 할당(Assign)에 국한된다.
이 말은,
타입 스크립트가 튜플을 검사할 때는 처음 값을 할당할 때만 엄격하게 검사 한다는 뜻이다.
런타임 시점에는, 자바스크립트의 배열 메서드 (push, splice)가 튜플에도 작동한다는 뜻이기 때문에,
그러므로 배열 메서드인 push나 pop, slice 을 이용해 고정된 길이를 무시하고 요소를 추가하거나 삭제할 수 있다.
따라서, 타입 시스템만 믿고 있으면 런타임에서 문제가 생길 수 있다는 점을 주의해야 하고
타입 안정성을 위해 readonly 등을 추가로 써야 안전하다.
const fixed: readonly [number, string] = [1, "hi"];
fixed.push("new"); // → 완전히 막힘
출처 : 한눈에 보는 타입 스크립트(herophy님 블로그), 한 입 크기로 잘라먹는 타입 스크립트,Chat GPT