한국어

TypeScript const 단언의 강력한 불변 타입 추론 기능을 활용하여 프로젝트의 코드 안전성과 예측 가능성을 향상시키세요. 실용적인 예제를 통해 효과적인 사용법을 배워보세요.

TypeScript Const 단언: 견고한 코드를 위한 불변 타입 추론

JavaScript의 상위 집합인 TypeScript는 동적인 웹 개발 세계에 정적 타이핑을 도입했습니다. 그 강력한 기능 중 하나는 컴파일러가 변수의 타입을 자동으로 추론하는 타입 추론입니다. Const 단언은 TypeScript 3.4에 도입되어 타입 추론을 한 단계 더 발전시켜, 불변성을 강제하고 더 견고하며 예측 가능한 코드를 만들 수 있게 해줍니다.

Const 단언이란 무엇인가요?

Const 단언은 TypeScript 컴파일러에게 어떤 값이 불변임을 의도한다는 것을 알리는 방법입니다. 리터럴 값이나 표현식 뒤에 as const 구문을 사용하여 적용합니다. 이는 컴파일러에게 표현식에 대해 가능한 가장 좁은(리터럴) 타입을 추론하고 모든 속성을 readonly로 표시하도록 지시합니다.

본질적으로 const 단언은 단순히 변수를 const로 선언하는 것보다 더 강력한 수준의 타입 안전성을 제공합니다. const는 변수 자체의 재할당을 막지만, 변수가 참조하는 객체나 배열의 수정을 막지는 않습니다. Const 단언은 객체의 속성 수정 또한 방지합니다.

Const 단언 사용의 이점

실용적인 예제

예제 1: 리터럴 기본 사용법

const 단언이 없으면 TypeScript는 message의 타입을 string으로 추론합니다:


const message = "Hello, World!"; // 타입: string

const 단언을 사용하면 TypeScript는 타입을 리터럴 문자열 "Hello, World!"로 추론합니다:


const message = "Hello, World!" as const; // 타입: "Hello, World!"

이를 통해 리터럴 문자열 타입을 더 정밀한 타입 정의 및 비교에 사용할 수 있습니다.

예제 2: 배열과 함께 Const 단언 사용하기

색상 배열을 생각해 봅시다:


const colors = ["red", "green", "blue"]; // 타입: string[]

배열이 const로 선언되었더라도 여전히 그 요소를 수정할 수 있습니다:


colors[0] = "purple"; // 오류 없음
console.log(colors); // 출력: ["purple", "green", "blue"]

const 단언을 추가하면 TypeScript는 배열을 읽기 전용 문자열 튜플로 추론합니다:


const colors = ["red", "green", "blue"] as const; // 타입: readonly ["red", "green", "blue"]

이제 배열을 수정하려고 하면 TypeScript 오류가 발생합니다:


// colors[0] = "purple"; // 오류: 'readonly ["red", "green", "blue"]' 타입의 인덱스 시그니처는 읽기만 허용합니다.

이것은 colors 배열이 불변으로 유지되도록 보장합니다.

예제 3: 객체와 함께 Const 단언 사용하기

배열과 유사하게, 객체도 const 단언을 사용하여 불변으로 만들 수 있습니다:


const person = {
  name: "Alice",
  age: 30,
}; // 타입: { name: string; age: number; }

const를 사용하더라도 person 객체의 속성을 수정할 수 있습니다:


person.age = 31; // 오류 없음
console.log(person); // 출력: { name: "Alice", age: 31 }

const 단언을 추가하면 객체의 속성이 readonly가 됩니다:


const person = {
  name: "Alice",
  age: 30,
} as const; // 타입: { readonly name: "Alice"; readonly age: 30; }

이제 객체를 수정하려고 하면 TypeScript 오류가 발생합니다:


// person.age = 31; // 오류: 'age'는 읽기 전용 속성이므로 할당할 수 없습니다.

예제 4: 중첩된 객체 및 배열과 함께 Const 단언 사용하기

Const 단언은 중첩된 객체와 배열에 적용하여 깊은 불변 데이터 구조를 만들 수 있습니다. 다음 예제를 고려해 보세요:


const config = {
  apiUrl: "https://api.example.com",
  endpoints: {
    users: "/users",
    products: "/products",
  },
  supportedLanguages: ["en", "fr", "de"],
} as const;

// 타입:
// {
//   readonly apiUrl: "https://api.example.com";
//   readonly endpoints: {
//     readonly users: "/users";
//     readonly products: "/products";
//   };
//   readonly supportedLanguages: readonly ["en", "fr", "de"];
// }

이 예제에서 config 객체, 그 안에 중첩된 endpoints 객체, 그리고 supportedLanguages 배열은 모두 readonly로 표시됩니다. 이를 통해 런타임에 구성의 어떤 부분도 우발적으로 수정되지 않도록 보장합니다.

예제 5: 함수 반환 타입과 함께 Const 단언 사용하기

함수가 불변 값을 반환하도록 보장하기 위해 const 단언을 사용할 수 있습니다. 이는 입력을 수정하거나 가변 출력을 생성해서는 안 되는 유틸리티 함수를 만들 때 특히 유용합니다.


function createImmutableArray(items: T[]): readonly T[] {
  return [...items] as const;
}

const numbers = [1, 2, 3];
const immutableNumbers = createImmutableArray(numbers);

// immutableNumbers의 타입: readonly [1, 2, 3]

// immutableNumbers[0] = 4; // 오류: 'readonly [1, 2, 3]' 타입의 인덱스 시그니처는 읽기만 허용합니다.

사용 사례 및 시나리오

구성 관리

Const 단언은 애플리케이션 구성을 관리하는 데 이상적입니다. 구성 객체를 as const로 선언함으로써 애플리케이션 수명 주기 동안 구성이 일관되게 유지되도록 보장할 수 있습니다. 이는 예기치 않은 동작으로 이어질 수 있는 우발적인 수정을 방지합니다.


const appConfig = {
  appName: "My Application",
  version: "1.0.0",
  apiEndpoint: "https://api.example.com",
} as const;

상수 정의

Const 단언은 특정 리터럴 타입으로 상수를 정의하는 데에도 유용합니다. 이를 통해 타입 안전성과 코드 명확성을 향상시킬 수 있습니다.


const HTTP_STATUS_OK = 200 as const; // 타입: 200
const HTTP_STATUS_NOT_FOUND = 404 as const; // 타입: 404

Redux 또는 기타 상태 관리 라이브러리와 함께 사용하기

Redux와 같은 상태 관리 라이브러리에서 불변성은 핵심 원칙입니다. Const 단언은 리듀서와 액션 생성자에서 불변성을 강제하여 우발적인 상태 변이를 방지하는 데 도움이 될 수 있습니다.


// Redux 리듀서 예제

interface State {
  readonly count: number;
}

const initialState: State = { count: 0 } as const;

function reducer(state: State = initialState, action: { type: string }): State {
  switch (action.type) {
    default:
      return state;
  }
}

국제화 (i18n)

국제화 작업을 할 때, 지원되는 언어 집합과 해당 로케일 코드를 갖게 되는 경우가 많습니다. Const 단언은 이 집합이 불변으로 유지되도록 보장하여 i18n 구현을 손상시킬 수 있는 우발적인 추가나 수정을 방지할 수 있습니다. 예를 들어, 영어(en), 프랑스어(fr), 독일어(de), 스페인어(es), 일본어(ja)를 지원한다고 상상해 보세요:


const supportedLanguages = ["en", "fr", "de", "es", "ja"] as const;

type SupportedLanguage = typeof supportedLanguages[number]; // 타입: "en" | "fr" | "de" | "es" | "ja"

function greet(language: SupportedLanguage) {
  switch (language) {
    case "en":
      return "Hello!";
    case "fr":
      return "Bonjour!";
    case "de":
      return "Guten Tag!";
    case "es":
      return "¡Hola!";
    case "ja":
      return "こんにちは!";
    default:
      return "Greeting not available for this language.";
  }
}

제한 사항 및 고려 사항

Const 단언의 대안

Const 단언은 불변성을 강제하는 강력한 도구이지만, 고려할 수 있는 다른 접근 방식도 있습니다:

모범 사례

결론

TypeScript const 단언은 코드에서 불변성을 강제하고 타입 안전성을 향상시키는 데 유용한 도구입니다. as const를 사용하여 컴파일러에게 값에 대해 가능한 가장 좁은 타입을 추론하고 모든 속성을 readonly로 표시하도록 지시할 수 있습니다. 이는 우발적인 수정을 방지하고, 코드 예측 가능성을 높이며, 더 정밀한 타입 검사를 가능하게 합니다. const 단언에는 몇 가지 제한 사항이 있지만, TypeScript 언어에 강력한 추가 기능이며 애플리케이션의 견고성을 크게 향상시킬 수 있습니다.

TypeScript 프로젝트에 const 단언을 전략적으로 통합함으로써 더 신뢰할 수 있고 유지 관리가 용이하며 예측 가능한 코드를 작성할 수 있습니다. 불변 타입 추론의 힘을 받아들여 소프트웨어 개발 방식을 한 단계 끌어올리세요.