본문 바로가기

Frontend/Typescript

Rollup 번들러로 enum과 const enum 트랜스파일링해보기 바로 이전에 enum은 어떻게 써야 하는지에 대한 글을 쓴 적이 있었다. https://gugu76.tistory.com/130 enum과 const enum을 비교하는 내용이 있었는데, 해당 글을 작성하다 보니 직접 트랜스파일링해서 결과를 보고 싶다는 생각이 들었다. 그래서 Rollup 번들러를 사용해서 간단하게나마 enum을 트랜스파일링해보고 결과를 확인해 보았다. Rollup Rollup도 Webpack 같은 자바스크립트 번들러 중 한 종류이다. Rollup은 빌드 결과물을 ES6 모듈 형태로 만들 수 있다. 이는, 사용자가 라이브러리의 코드 일부만 사용하게 되면 해당 부분만 번들 결과물에 포함시킬 수 있게 되는 것이다. 그래서, 사용하지 않는 코드를 빌드 단에서 제거하는 트리 쉐이킹 기법을 활용해.. 더보기
enum은 어떻게 써야하는가? 이번에 프로젝트를 진행하면서 상수 값을 저장할 때 계속해서 enum 타입을 사용해 왔다. 그런데, 타입스크립트를 계속 공부하다 보니 enum 타입에 대한 논란이 있는 것을 알게 되었다. 그 논란에 대해서 좀 자세히 알아보고 앞으로 어떻게 enum을 사용할지 생각해 보면 좋을 거 같아서 글을 쓰게 되었다. 일단, 나는 아래 글을 보고 나서 해당 문제에 대해서 알아보게 되었다. https://engineering.linecorp.com/ko/blog/typescript-enum-tree-shaking 위 글은 라인 기술 블로그 글인데, 한 줄 요약하자면 enum 타입을 쓰면 tree-shaking이 되지 않으니 const enum이나 union 타입을 쓰라는 것이었다. 이렇게만 말하면 무슨 뜻인지 모르겠으니.. 더보기
[이펙티브 타입스크립트] 타입스크립트의 고급 기능을 잘 활용해보자 타입의 중복 제거 태그된 유니온에서 다음과 같은 타입의 중복이 발생할 수 있다. interface SaveAction { type: 'save'; // ... } interface LoadAction { type: 'load'; // ... } type Action = SaveAction | LoadAction; type ActionType = 'save' | 'load' // 타입 중복 그런 경우 아래와 같이 변경해 주면 좋다. type ActionType = Action['type']; // 타입은 'save' | 'load' 이렇게 타입을 지정해주면 Action 유니온에 타입을 더 추가한 경우 ActionType은 자동으로 해당 타입까지 포함하게 된다. 또한, 제네릭 타입을 사용하면 타입의 중복을 .. 더보기
[이펙티브 타입스크립트] 타입을 명확하고 일관성 있게 써보자 이전에 이펙티브 타입스크립트를 한 번 읽어본 적이 있었다. 하지만, 그때는 타입스크립트는 그냥 타입만 지정하는 정도로만 알고 있었기 때문에 하나도 이해를 못 했었다. 요즘 TIFY 프로젝트를 진행하며 타입을 명확하고 안전성 있게 써보는 것에 관심이 많아졌고, 이제는 이 책을 다시 읽어볼 수 있는 단계가 된 것 같아 다시 읽어보게 되었다. 이전보다 훨씬 더 넓은 시야로 타입스크립트를 이해할 수 있는 시간이었다. 책에 있는 설명들과 내가 이해한 개념을 합쳐 글을 써보았다. 구조적 타이핑자바스크립트는 덕 타이핑(구조적 타이핑) 기반으로 동작한다. 타입스크립트 또한 이 방식을 모델링해서 동작하는데, 필요한 매개 변수 값이 요구 사항을 만족한다면 신경 쓰지 않고 실행시킨다. 아래 예시를 한 번 살펴보자.inter.. 더보기
조건부 타입과 유틸리티 타입 조건부 타입 조건부 타입은 삼항 연산자를 사용해서 타입을 정의하는 타입이다. /** * 조건부 타입 */ type A = number extends string ? string : number; // number 타입 type ObjA = { a: number; } type ObjB = { a: number; b: number; } type B = ObjB extends ObjA ? number : string; // number 타입 /** * 제네릭과 조건부 타입 */ type StringNumberSwitch = T extends number ? string : number; let varA: StringNumberSwitch; // string 타입 let varB: StringNumberSwit.. 더보기
타입 조작하기 타입 조작하기 타입 조작하기는 기본 타입이나 별칭 또는 인터페이스로 만든 원래 존재하던 여러 가지 타입들을 타입스크립트의 특수한 문법을 이용해서 상황에 따라 다른 타입으로 변환하는 기능이다. 제네릭도 그런 관점에서 타입 조작하기에 속한다. 이제부터 타입 조작하기에 속하는 것들을 자세히 알아보자. 인덱스드 액세스 타입 인덱스드 액세스 타입은 객체, 배열, 튜플 타입에서 특정 프로퍼티/요소의 타입을 추출하는 타입인데, 아래 코드에서 세 경우를 모두 확인해볼 수 있다. /** * 인덱스드 액세스 타입 */ interface Post { title: string; content: string; author: { id: number; name: string; } } function printAuthorInfo(a.. 더보기
제네릭 제네릭 /** * 제네릭 */ // 제네릭 함수 function func(value: T): T { return value; } let num = func(2); let bool = func(true); let str = func('string'); let arr = func([1, 2, 3]); // 튜플 위 함수에서 반환값의 타입은 함수 호출 시 결정된다. 튜플 타입을 넣어주고 싶은 경우, 타입 단언을 사용하는 것보다 위와 같이 나타내는 것이 더 좋다. 타입 변수 응용하기 /** * 첫 번째 사례 */ function swap(a: T, b: U): [U, T] { return [b, a]; } const [a, b] = swap('1', 2); /** * 두 번째 사례 */ function retu.. 더보기
인터페이스와 클래스 인터페이스 인터페이스는 타입 별칭과 구분할 수 있는데, 아직 타입 별칭에 대해서는 다루지 않았기 때문에 타입 별칭 부분에서 비교해보도록 하자. /** * 인터페이스 */ interface Person { readonly name: string; age?: number; sayHi(): void; sayHi(a: number, b: number): void; } const person: Person = { name: '이정환', sayHi: function () { console.log('Hi'); } } 인터페이스를 사용해서 타입을 정의하려면 위와 같이 사용하면 된다. 위 코드만 보면 타입 별칭과 특별히 차이가 없는 것처럼 느낄 수 있지만, 인터페이스에는 타입 별칭과 다른 특징이 있다, 그 부분은 아래에.. 더보기