mingg IT

[이펙티브 타입스크립트] 8장 타입스크립트로 마이그레이션 하기 본문

FrontEnd

[이펙티브 타입스크립트] 8장 타입스크립트로 마이그레이션 하기

mingg123 2023. 8. 19. 20:18

https://mingg123.tistory.com/226

 

[TS] 이펙티브 타입스크립트 리뷰

1장 타입스크립트 알아보기 https://mingg123.tistory.com/225 [이펙티브 타입스크립트] 1장 구조적 타이핑 mingg IT [이펙티브 타입스크립트] 1장 구조적 타이핑 본문 FrontEnd [이펙티브 타입스크립트] 1장 구

mingg123.tistory.com

 

아이템 58 모던 자바스크립트로 작성하기

타입스크립트로 마이그레이션을 할 경우 자바스크립트 코드부터 최신 버전으로 바꾸자.

 

 

타입스크립트 도입시 ECMAScript 모듈과 ES2015 클래스가 중요함

ES로 전환시 웹팩 혹은 ts-node 도구가 필요할 수 있음. 

 

ES 모듈로 전환 

ES로 전환 전

const b = require('./b');
console.log(b.name);

const name = 'Module B';
module.exports = {name};

 

ES 전환 후

import * as b from './b';
console.log(b.name);

export const name = 'Module B';

 

프로토타입 대신 클래스를 이용하기

프로토타입

function Person(first, last){
    this.first = first;
    this.last = last;
}

Person.prototype.getName = function() {
    return this.first + ' ' + this.last;
}

const marie = new Person('Marie', 'Curie');
const personName = marie.getName();

사실 난 한번도 프로토타입형식을 사용해본적이 없기는 하다.

 

class

class Person {
    first: string;
    last: string;

    constructor(first: string, last: string) {
    	this.first = first;
        this.last = last;
    }
    
    getName(){
    	return this.first + ' ' + this.last;
    }
}

프로토타입으로 구현한 Person 객체보다 클래스로 구현한 객체가 문법이 간결하고 직관적임. 

 

프로토타입 객체에 마우스를 올려서 class로 변환도 가능하다함.

 

var 대신 let, const 사용하기

function foo() {
    bar();
    function bar(){
        console.log('hello');
    }
}

foo() 함수를 호출하게되면 함수 선언식으로인해 호이스팅이 발생하고, hello 가 출력됨 

const bar = () => {} 를 이용해서 써라. 

 

 

for(;;) 대신 for-of 또는 배열 메소드 사용하기 

for-of를 이용하고, 인덱스가 필요할 경우엔 forEach를 사용해라.

for-in 문법도 존재하지만 몇가지 문제점이 있다함.

 

배열 순회시 for-in의 문제점

 

배열의 크기를 제대로 반영하지 못함

const arr = [];
arr[5] = "foobar";

for .. of 를 사용한 경우

 

for .. in을 사용한 경우

arr[5] 에 값을 넣고 순회하면서 출력하면 우리는 undefined 5번 출력하고, foobar출력을 기대할 것이다.

허나 for in을 이용하면 5와 undefined가 나옴

 

배열의 순서를 보장하지 못한다고는 하는대 재현은 되지 않았음.

 

그렇다면 for-in을 사용해야 하는 경우는 언제일까?

배열의 key-value를 이용해서 순회할 경우 쓸 수 있겠다. (허나 map이나 set이 있는데 굳이 for-in을 사용할까 싶다.)

 

구조 분해 할당 사용하기

구조 분해 할당 예시

const props = obj.props;
const a = props.a;
const b = props.b;

const {props} = obj;
const {a,b} = props;


// 한번에 사용하는 예시
const {props: {a,b}} = obj;

 

함수 매개변수 기본값 사용하기

함수 매개변수 기본값 사용 예시

function parseNum(str, base) {
    base = base || 10;
    return parseInt(str, base);
}

 

모던 자바스크립트에서는 매개변수에 기본 값을 직접 지정하 수 있음.

function parseNum(str, base = 10){
    return parseInt(str, base);
}

 

프로미스나 콜백 대신 async/await 사용하기

연관 배열에 객체 대신 Map과 Set 사용하기 

 

타입스크립트에 use strict 넣지 않기 

'use strict'를 이용하면 버그가 될 수 있는 코드에 오류를 표시해준다.

허나 타입스크릅트에서 수행되는 검사가 더 엄격하기 때문에 타입스크립트에서 'use strict'는 무의미하다.

 

 

 

아이템 59 타입스크립트 도입 전에 @ts-check와 JSDoc으로 시험해보기

 

@ts-check를 이용하면 타입스크립트 전환시에 어떤 문제가 발생하는지 미리 알 수 있다.

마이그레이션을 진행하기 전에 체크해보면 좋은 옵션일 듯 하다.

 

@ts-check 예시

// @ts-check
const person = {first: 'Grace', last: 'Hopper'};

person.first * 2 // 에러 발생 산술 연산 오른쪽 'any', 'number' 'bigInt' 또는 열거영이여야 합니다.

 

그 밖에도 선언되지 않은 전역 변수, 알 수 없는 라이브러리에서 사용이 가능함

JSDoc 주석을 이용하면 자바스크립트 상태에서도 타입 단언과 추론이 가능함. 

 

 

아이템 60 allowJs로 타입스크립트와 자바스크립트 같이 사용하기 

타입스크립트와 자바스크립트가 공존하는 방법의 핵심은 allowJs 컴파일러 옵션임 

 

allowJs 적용 방법

$ browserify index.ts -p [ tsify —allowJs ] > bundle.js

 

유닛테스트를 진행할 경우 ts-jest 설치이후 jest.config.js 에 전달할 타입스크립트 소스를 지정

module.exports = { 
    transform: {
    ,^.+\\.tsx?$,: 'ts-jest',
    },
};

 

 

 

아이템 61 의존성 관계에 따라 모듈 단위로 전환하기 

다른 모듈에 의존하지 않는 최하단 모듈부터 작업을 시작해서 의존성 최상단에 있는 모듈을 마지막으로 완성해야함. 

 

  • 서드파티 라이브러리 같은 경우에는 아래와 같이 설치하면됨(예시 lodash)
    • npm install --save-dev @types/lodash 
  • 마이그레이션을 진행할때는 타입 정보만 추가하고 리팩토링을 해서는 안됨 
  • 임의로 any로 넣고 추후 바꾸기
  • 타입 단언문 사용하기 

 

 

아이템 62 마이그레이션의 완성을 위해 noImplictAny 설정하기 

noImplictAny 옵션을 이용하면 숨겨진 타입 오류를 찾을 수 있다.

로컬에서만 설정하고 수정된 부분만 커밋하면 점진적 마이그레이션이 가능하다.

가장 강력한 설정은 strict: true 옵션이다.

 

 

 

Comments