JS, TS deep immutable types 만들기
왜 궁금?
코딩을 하게되면 이 배열 또는 객체가 immutable
하여 외부의 영향을 안받는다는 확신이 필요할 때가 있습니다.
그러기위해 저는 TS로 개발을 하면 동결
을 위해 as const
구문을 많이 사용합니다. const assertion
이라고 불리는 것으로
객체를 readonly 상태 즉 immutable한 객체로 만들어 줍니다.
하지만 컴파일
타임에만 해당하는 것이고 JS가 된 파일을 보면 일반 객체로 풀려있는 것을 발견할 수 있습니다.
목적은 런타임
에도 객체 동결을 만드는 것입니다.
JS, Object.freeze
하지만 이미 JS에는 Object.freeze
라는 훌륭한 객체 메소드가 있습니다.
얕은 동결
obj = {
internal: {}
};
Object.freeze(obj);
obj.internal.a = 'aValue';
obj.internal.a // 'aValue'
하지만 객체의 깊이 1 까지만 동결을 해주기 때문에 재귀 함수를 통해 객체 내부 전체를 동결 시켜보도록 하겠습니다.
function deepFreeze<T>(obj: T) {
var propNames = Object.getOwnPropertyNames(obj);
for (let name of propNames) {
let value = (obj as any)[name];
if (value && typeof value === "object") {
deepFreeze(value);
}
}
return Object.freeze(obj);
};
const bill = deepFreeze({
name: "Bill",
profile: {
level: 1,
},
scores: [90, 65, 80],
} as const);
이제 런타임
에도 객체나 배열을 deep immutable 상태로 만들어 사용할 수 있게되었습니다.
Immutable Type
위의 방법들로 충분히 deep immtable이 되었습니다.
하지만 TS에는 타입 추론이라는 것이 존재하는데
명시적으로 bill
이 동결상태라는 것을 어떻게 나타낼 수 있을까요?
type Person = {
readonly name: string;
readonly profile: {
readonly level: number;
};
readonly scores: number[];
};
위와 같이 귀찮게도 모든타입에 readonly
를 적어주어야 할까요?
운이 좋게도 재귀적인 type을 만들어 주면 그럴 필요가 없습니다.
...
type Immutable<T> = {
readonly [K in keyof T]: Immutable<T[K]>;
};
const bill: Immutable<Person> = deepFreeze({
name: "Bill",
profile: {
level: 1,
},
scores: [90, 65, 80],
});
위와 같이 사용하여 런타임에도 컴파일 타임에도 명시적으로 이 객체는 동결
되었다는 것을 알 수 있게 되었습니다.
Author And Source
이 문제에 관하여(JS, TS deep immutable types 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ehgks0000/JS-TS-deep-immutable-types-만들기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)