같은 number 타입이지만 kg, cm로 성질이 다른 값들...
좀더 구체적인 타입을 정의하고 싶을 때 이렇게 씀
타입 안정성을 올릴 수 있는 방법 중 하나인 브랜딩 타입
const length = 80 as number & {__brand:"cm"}; // cm
const weight = 90 as number & {__brand:"kg"} // kg
function showWeight (weight:number & {__brand:"kg"}) {
return console.log("weight ", weight)
}
function showLength (length:number & {__brand:"cm"}) {
return console.log("length ", length)
}
showWeight(weight)
showLength(length)
showWeight(12 as number & {__brand:"kg"})
const sum :number = weight + length
console.log(sum)
같은 number이기 때문에 더하기는 됨
보통 이렇게 정의해놓고 쓴다함
interface Brand<T, B> {
value: T;
_type: B;
}
type Length = Brand<number, "cm">;
type Weight = Brand<number, "kg">;
const length: Length = { _type: "cm", value: 80 };
const weight: Weight = { _type: "kg", value: 90 };
확장 버전
interface Length extends Brand<number, "cm"> {
unit: "centimeter";
}
interface Weight extends Brand<number, "kg"> {
unit: "kilogram";
}
const length: Length = { _type: "cm", value: 80, unit: "centimeter" };
const weight: Weight = { _type: "kg", value: 90, unit: "kilogram" };
function showWeight(weight: Weight) {
console.log("weight", weight.value, weight.unit);
}
function showLength(length: Length) {
console.log("length", length.value, length.unit);
}
vs
음 enum이랑 똑같은 거 아닌가.... 하는 느낌
enum과 브랜딩 타입 모두 타입을 구체화하는건 맞음
하지만 다름
enum은 관련된 상수들의 집합임
브랜딩 타입은 동일한 기본타입을 구체화하는 거임
위의 예시를 enum으로 쓴다면
enum Unit {
CM = "cm",
KG = "kg"
}
interface Length {
value: number;
unit: Unit.CM;
}
interface Weight {
value: number;
unit: Unit.KG;
}
const length: Length = { value: 80, unit: Unit.CM };
const weight: Weight = { value: 90, unit: Unit.KG };
function showWeight(weight: Weight) {
console.log("weight", weight.value, weight.unit);
}
function showLength(length: Length) {
console.log("length", length.value, length.unit);
}
성질 비슷한 것들 묶어놓는 느낌
근데 요즘 enum 잘 안 씀
이유는 라인에서도 알려주고 다른 참고 블로그 많음
https://engineering.linecorp.com/ko/blog/typescript-enum-tree-shaking
1. enum 은 숫자형일 때 자동적으로 값이 할당됨
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
console.log(Direction.Up); // 출력: 0
console.log(Direction.Down); // 출력: 1
console.log(Direction.Left); // 출력: 2
console.log(Direction.Right); // 출력: 3
let myDirection: Direction = Direction.Up;
console.log(myDirection); // 출력: 0
myDirection = 5; // 허용됨, 하지만 의도하지 않은 값
console.log(myDirection); // 출력: 5
=> vscode에서 오류는 띄워주는데, 실행은 되는 거 같음
=> 이거 대응하기 위해서 이렇게 const를 쓴다고 하는데
const enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
왜 나는 이렇게 써도 값이 할당되지...?
다른 곳에서는 이렇게 쓰면 된다고 함
근데 저것도 문제점이 있음
1. babel-plugin-const-enum 설정이 필요하다고 함
2. 문자열 값을 유니코드로 생성한다고 함 (빌드 파일 커짐)
const enum EnumKeyboard {
"GREETING" = "안녕하세요. 반가워요!!"
}
console.log(EnumKeyboard['GREETING']);
/* JS */
console.log("\uC548\uB155\uD558\uC138\uC694. \uBC18\uAC00\uC6CC\uC694!!" /* 'GREETING' */);
=> 여기에 대응하는 방법으로는
그냥 객체 만들어서 as const 붙인 다음에 이걸 type IType = typeof 객체 이름
요렇게 쓰신다고 함
2. 트리 셰이킹 이슈
트리 셰이킹 :
=> 빌드 파일 만들 때 쓰지 않는 코드들은 제거해 주는 거. 경량화 목적임
=> 웹팩에서는 ES6 모듈 시스템 사용하고 mode : production 하면 자동으로 활성화 함
웹팩 이외에도 빌드 툴들이 빌드 할 때 거치는 과정 중 하나임
타입도 마찬가지로 컴파일 단계에서 타입 검사만 하고 사라짐
근데 enum은 자바스크립트 코드로 컴파일 되기 때문에 빌드 파일에 남아 있음 <= 경량화가 안됨 최적화된 번들이 아님
enum 은 타입인데.. 타입 같지 않는 느낌...
그냥 다른 거 쓰는 게 나음
저러한 한계 찐 대안법
리터럴 타입과 유니언 타입
type Unit = "cm" | "kg";
function printUnit(unit: Unit) {
console.log(unit);
}
printUnit("cm"); // 올바른 호출
printUnit("kg"); // 올바른 호출
이렇게 쓰면 됨
enum 요즘 안 쓴다고 해서 필요할 때 저렇게 썼는데
왜 안 쓰는지 알게 됨
진짜 쓸 필요 없었네...
'TIL' 카테고리의 다른 글
icon suspense lazy 기능으로 넣기 (0) | 2024.07.02 |
---|---|
vite와 swc (1) | 2024.06.30 |
jest (0) | 2024.06.26 |
이미지 public에 넣기 vs src에 넣고 import하기 ++ 이미지 suspense로 감싸서 가져오기 (1) | 2024.06.24 |
cra 없이 webpack 개발 환경 설정하기 (0) | 2024.06.23 |
댓글