1. JavaScript에서의 Array 사용
JavaScript에서는 하나의 배열에 숫자, 문자열, 함수 등 다양한 타입의 데이터를 혼합해서 넣을 수 있습니다.
const array = [1, "JavaScript", () => console.log("Hello")];
console.log(array[0]); // 1
console.log(array[1]); // "JavaScript"
이처럼 JavaScript의 배열은 다양한 타입의 데이터를 자유롭게 담을 수 있는 유연성을 제공하지만, 잘못된 데이터가 배열에 포함될 가능성도 큽니다. 이로 인해 데이터의 타입 일관성을 보장하기 어렵고, 예상치 못한 버그가 발생할 수 있습니다.
2. TypeScript에서 Array 타입 선언 방법
TypeScript에서는 Array 타입을 지정하는 두 가지 방법이 있습니다.
1. 타입 뒤에 대괄호 []를 붙이는 방식
const numbers: number[] = [1, 2, 3];
const strings: string[] = ["TypeScript", "JavaScript"];
2. 제네릭 형태로 Array<타입>을 사용하는 방식
const numbers: Array<number> = [1, 2, 3];
const strings: Array<string> = ["TypeScript", "JavaScript"];
이 두 방법은 동일한 Array 타입을 정의하며, 배열 내의 요소가 지정된 타입을 따르도록 강제합니다. 만약 다른 타입의 데이터를 배열에 추가하려고 시도하면, TypeScript는 컴파일 시점에 오류를 발생시켜 잘못된 타입 사용을 방지합니다.
만약 배열에 여러 타입의 원소를 추가하고 싶다면 ?
=> union타입 사용
3. Union 타입을 활용한 Array 선언
TypeScript에서 Union 타입을 사용하면 여러 타입의 요소를 담을 수 있는 Array를 선언할 수 있습니다. 예를 들어, 숫자와 문자열이 혼합된 배열이 필요한 경우 Union 타입을 적용할 수 있습니다.
const mixedArray1: Array<number | string>[] = [1, "TypeScript"];
const mixedArray2: number[] | string[] = [1, "TypeScript"];
const mixedArray3: (number | string)[] = [1, "TypeScript"];
이 방식은 데이터의 유연성을 제공하지만, 지나치게 많은 타입을 허용할 경우 오히려 코드의 안전성이 저하될 수 있습니다.
TypeScript에서 Array 타입은 배열 내 요소의 타입을 고정할 수 있지만, 배열의 길이는 고정할 수 없습니다. 즉, TypeScript의 일반적인 Array 타입은 동일한 타입의 요소를 여러 개 담을 수 있으나, 특정 길이와 위치에 따른 타입을 제한하지는 못합니다. 이 문제를 해결하기 위해 Tuple 타입이 추가되었습니다.
3. Tuple 타입 선언 방법과 예시
Tuple은 배열 타입의 하위 타입으로 기존 타입스크립트의 배열 기능에 길이 제한까지 추가한 타입시스템입니다. Tuple은 각 요소가 특정 타입을 갖도록 강제할 수 있습니다. 예를 들어, 특정한 위치에 number, string, boolean 타입을 순서대로 넣어야 하는 경우, Tuple을 사용해 정의할 수 있습니다.
let tuple: [number, string, boolean] = [1, "TypeScript", true];
Tuple은 배열 요소의 위치별로 타입을 지정할 수 있어, 데이터의 일관성을 유지하고, 잘못된 타입이 들어가는 것을 방지할 수 있습니다.
1. 활용 예시: React의 useState훅
React 16.8 버전에서 도입된 useState는 컴포넌트에서 상태를 관리할 수 있도록 하는 Hook입니다. useState가 반환하는 Tuple의 첫 번째 요소는 현재 상태 값을, 두 번째 요소는 상태를 업데이트하는 함수를 의미합니다. 이러한 Tuple 구조를 사용함으로써 각 위치의 값에 명확한 역할을 부여할 수 있습니다.
import { useState } from "react";
const [count, setCount] = useState<number>(0); // [number, React.Dispatch<SetStateAction<number>>]
위 예시에서 count는 현재 상태 값을 나타내고, setCount는 상태를 변경하는 함수입니다. useState가 반환하는 Tuple을 구조 분해 할당하여 각 변수에 명확한 역할을 부여할 수 있으며, 구조 분해 할당을 통해 사용자가 변수 이름을 자유롭게 설정할 수 있습니다. 이로 인해 코드의 가독성이 높아지고, 타입 안전성이 강화됩니다.
또한, useState는 컴포넌트에서 의도하지 않은 값에 접근하는 오류를 방지할 수 있습니다. 예를 들어, 첫 번째 요소는 상태 값으로만, 두 번째 요소는 상태 업데이트 함수로만 사용되므로, 역할이 구분되어 잘못된 사용을 방지할 수 있습니다.
4. Tuple과 Array를 혼합하여 사용하기
TypeScript에서는 Tuple과 Array를 함께 사용하여, 일부 요소는 고정된 타입과 순서를 갖고, 그 이후의 요소들은 동일한 타입의 데이터로 유연하게 확장할 수 있도록 만들 수 있습니다. 예를 들어, 첫 번째와 두 번째 요소는 고정된 타입과 순서를 가지며, 이후 요소들은 특정 타입의 배열로 확장할 수 있습니다.
// 첫 번째와 두 번째 요소는 [string, number]의 Tuple이고, 이후는 number 타입의 Array
let mixed: [string, number, ...number[]] = ["TypeScript", 2023, 1, 2, 3, 4];
5. Tuple의 옵셔널(Optional) 요소
TypeScript에서는 Tuple 내에서도 옵셔널 요소를 정의할 수 있습니다. 이는 특정 위치의 값이 필수적이지 않도록 설정할 때 유용합니다. 옵셔널 요소는 물음표(?)를 사용해 정의하며, 이 경우 해당 위치에 값이 있을 수도 있고, 없을 수도 있습니다.
// 두 번째 요소인 number가 옵셔널
let optionalTuple: [string, number?] = ["TypeScript"];
optionalTuple = ["TypeScript", 2023]; // 둘 다 가능
옵셔널 요소와 Tuple을 혼합해 사용하면 특정 위치에 값이 없어도 되는 유연성을 제공하면서, 필요한 경우에만 데이터를 추가할 수 있어 보다 안전한 데이터 관리를 가능하게 합니다.
오늘은 TypeScript의 Array 타입과 Tuple타입에 대해 학습했다. Tuple 타입은 많이 사용해보지 않았다고 생각했는데, 자주 사용하던 useState가 Tuple 타입을 반환하고 있다는 사실을 잊고 있었다는 점이 살짝 부끄러웠다. 기본을 제대로 이해하고 적용하는 것이 중요하다는 것을 다시 한번 깨닫게 된 시간이었다.
'TypeScript' 카테고리의 다른 글
[TypeScript] TypeScript 타입 조합에 대해 알아보자 (0) | 2024.11.20 |
---|---|
[TypeScript] TypeScript의 Enum타입에 대해 알아보자 (1) | 2024.11.19 |
TypeScript의 any 와 unknown을 제대로 사용하는 법 (1) | 2024.11.08 |
객체 타입을 선언할 때 type ? interface ? 어떤 것을 사용해야하나 (3) | 2024.11.07 |
TypeScript 2일차 / TypeScript 문법을 뿌셔보자 ( 열거형, 인터페이스 ,타입 별칭) (0) | 2023.05.31 |