TypeScript에서 가변성과 불변성
이 글은 TypeScript에서의 가변성과 불변성 개념을 설명합니다.
YouTube Video
TypeScript에서 가변성과 불변성
가변성이란 무엇인가?
가변성이란 값이 변경될 수 있음을 의미합니다. 객체나 배열과 같은 참조 타입은 가변적 데이터 구조의 대표적인 예입니다.
가변 객체의 예
1type Person = { name: string; age: number };
2
3// Mutable Example: Object
4let person: Person = { name: "Alice", age: 25 };
5person.age = 26;
6console.log(person); // { name: "Alice", age: 26 }
이 코드에서 person
객체의 age
속성이 25
에서 26
으로 변경됩니다. 객체는 참조에 의해 전달되므로, person
변수에 저장된 메모리 주소의 내용이 수정됩니다.
가변 배열의 예
1// Mutable Example: Array
2let numbers: number[] = [1, 2, 3];
3numbers.push(4);
4console.log(numbers); // [1, 2, 3, 4]
이 코드에서 push
메서드를 사용해 원래 배열에 새로운 요소 4
를 추가합니다. 이로 인해 원래 배열이 수정되며, 이는 가변적인 작업입니다.
함수 내 예제
1// Mutable Example: Function
2function append(arr: number[], value: number): void {
3 arr.push(value); // Modify the original array
4 console.log(arr);
5}
6
7let nums: number[] = [1, 2, 3];
8append(nums, 4);
9console.log(nums); // [1, 2, 3, 4]
함수 내에서 가변적 작업을 수행하면 원래의 배열도 수정됩니다.
불변성이란 무엇인가?
불변성이란 값이 변경될 수 없음을 의미합니다. 원시 타입은 기본적으로 불변입니다.
불변 원시 타입의 예
1// Immutable Example: String
2let str: string = "hello";
3str[0] = "H"; // Error: Index assignment is not allowed
4console.log(str); // "hello"
문자열이 불변이기 때문에 문자열 str
의 첫 번째 문자를 H
로 변경하려고 해도 실패합니다.
함수 내 예제
1// Immutable Example: Function
2function increment(num: number): number {
3 num++; // This modifies only the local copy of num
4 return num;
5}
6
7let number: number = 10;
8console.log(increment(number)); // 11
9console.log(number); // 10 (original number remains unchanged)
숫자는 불변이기 때문에 함수 내의 작업이 원래 변수에 영향을 주지 않습니다.
배열에서의 불변 작업
배열은 가변적이지만, 원래 배열을 수정하지 않고 새 배열을 생성함으로써 불변 작업을 수행할 수 있습니다.
1// Create an array of numbers
2let numbers: number[] = [1, 2, 3];
3
4// Immutable Example: Creating a new array
5let newNumbers: number[] = [...numbers, 4];
6
7console.log(numbers); // [1, 2, 3] (original array is unchanged)
8console.log(newNumbers); // [1, 2, 3, 4] (new array with an added element)
여기에서 펼침 문법 (...
)이 사용되어 새 배열 newNumbers
가 생성됩니다. 원래의 numbers
배열이 변경되지 않으므로, 이는 불변 작업입니다.
불변 데이터 구조를 사용하는 이점
예측 가능성 향상
불변 데이터는 변경되지 않기 때문에 예기치 않은 수정 가능성을 줄이고 버그 발생 가능성을 낮춥니다.
불변성을 기반으로 한 라이브러리와의 호환성
React
및 Redux
와 같은 라이브러리는 종종 불변 데이터를 기반으로 설계되며, 적절히 사용하면 상태 관리가 더 쉬워집니다.
Object.freeze를 사용하여 객체를 불변으로 만들기
Object.freeze
를 사용하여 객체의 수정을 방지할 수 있습니다.
1// Create a frozen object (properties cannot be modified)
2const person = Object.freeze({ name: "Alice", age: 25 });
3
4// Attempt to modify a property (ignored in non-strict mode, error in strict mode)
5person.age = 26;
6
7console.log(person); // { name: "Alice", age: 25 }
그러나 Object.freeze
는 얕은 동결만 수행하므로 중첩 객체의 속성은 여전히 수정 가능합니다.
1// Create a frozen object with a nested object
2const user: Readonly<{ profile: { name: string } }> = Object.freeze({
3 profile: { name: "Bob" }
4});
5
6// Attempt to modify a nested property (this works because Object.freeze() is shallow)
7user.profile.name = "Charlie"; // No TypeScript error, but still mutable
8
9console.log(user.profile.name); // "Charlie" (nested object is still mutable)
완전히 불변한 객체를 만들려면 깊은 동결이 필요합니다.
1// Function to deeply freeze an object, making all nested objects immutable
2function deepFreeze<T>(obj: T): Readonly<T> {
3 Object.freeze(obj);
4 Object.getOwnPropertyNames(obj).forEach(prop => {
5 const value = (obj as any)[prop];
6 if (typeof value === "object" && value !== null) {
7 deepFreeze(value);
8 }
9 });
10 return obj;
11}
12
13// Create a deeply frozen object
14const user = deepFreeze({
15 profile: { name: "Bob" }
16});
17
18// Attempt to modify a nested property
19// (this will now throw an error in strict mode)
20user.profile.name = "Charlie"; // No TypeScript error, but modification is not allowed at runtime
21
22console.log(user.profile.name); // "Bob" (unchanged due to deep freeze)
요약
- 가변 데이터는 수정 가능하며 객체와 배열을 포함합니다.
- 불변 데이터는 수정할 수 없으며 문자열 및 숫자와 같은 원시 타입을 포함합니다.
- 펼침 문법 또는
map
과 같은 메서드를 사용하여 불변 데이터 작업을 수행할 수 있습니다. Object.freeze
및deepFreeze
를 사용하여 객체 수정을 방지할 수 있습니다.- 불변 데이터를 사용하면 더 예측 가능하고 오류 발생 가능성이 적은 코드를 작성할 수 있습니다.
불변 설계를 채택하면 코드 안전성과 가독성이 향상되므로 적극 활용하세요!
위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.