class User {
private _name: string;
private _age: number;
constructor(name: string, age: number) {
this._name = name;
this._age = age;
}
get name(): string {
return this._name;
}
get age(): number {
return this._age;
}
}
const user = new User('곰튀김', 28);
필드 변수가 많아지만 점점 관리가 어려워짐. constuctor나 getter는 WebStorm 이 만들어주기는 하지만, 코드가 길어져서 불편.
생성할 때 전부 초기값을 넣어야 해서 불편.
Builder 패턴을 적용해보기도 하지만 모델이 많아지면 역시 귀찮음.
interface User {
readonly name: string;
readonly age: number;
}
const user: User = {
name: '곰튀김',
age: 28,
};
타입 정의할 때 readonly로 정의해버림. set의 허용을 선택할 수 있음.
nested object 안에서도 각각 다 해줘야 함.
interface 나 type 이나 둘 다 똑같이 적용가능
type User = {
readonly name: string;
readonly age: number;
};
타입을 항상 미리 정의해 줘야 함.
type 이나 interface를 nested 영역에서 정의할 수 없음. 임시로 만들어지는 immutable 데이터에 대해서도 정의가 필요하고, export 해야할 경우가 많음.
const user = {
name: '곰튀김',
age: 28,
} as const;
object 데이터 생성과 함께 const 로 얼려버림.
nested objet 안에서도 각각 다 지정 해줘야 함.
별도의 타입을 만들어주지 않아도 되니까 임시로 데이터를 만들어 전달할 때 유용함.
생성시에 지정되는 것으로 이미 만들어진 데이터에 대해서 적용할 수 없음.
const user = {
name: '곰튀김',
age: 28,
};
Object.freeze(user);
이미 만들어진 object 를 immutable 하게 만들어줌.
nested 된 object 에는 적용되지 않음.
deepFreeze 같은 Util을 만들어서 전체 다 immutable 하게 만들 수 있음
deepFreeze.ts
const deepFreeze = (obj: any) => { Object.keys(obj).forEach((prop) => { if (typeof obj[prop] === "object" && !Object.isFrozen(obj[prop])) { deepFreeze(obj[prop]); } }); return Object.freeze(obj); };
(출처: 30-seconds-of-typescript)
이렇게 해봐도 compile time 에만 immutable이 유지될 뿐,
이미 js로 변환된 후 runtime 에서는 immutable이 유지되지 않더라.