
모던 자바스크립트란 ? 최신버전의 자바스크립트로, 현재는 ES2015(ES6) 버전부터 모던 자바스크립트라고 부르고 있다.
타입스크립트는 타입체크 기능도 있지만, 타입스크립트 코드를 특정 버전의 자바스크립트로 컴파일 하는 기능도 가지고 있다. 즉 타입스크립트의 컴파일러를 자바스크립트 트랜스파일러로 사용할 수 있다.
ECMAScript
ES2015부터는 임포트(import)와 익스포트(export)를 사용하는 ECMASciprt 모듈이 표준이 되었다.프로토타입 대신 클래스 사용하기
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 Person {
first: string
last: string
constructor(first: string, last: string) {
this.first = first
this.last = last
}
getName() {
return this.first + ' ' + this.last
}
}
const marie = new Person('Marie', 'Curie')
const personName = marie.getName()
클래스로 구현한 Person 객체가 문법이 간결하고 직관적이다.
편집기에서 프로토타입 객체에 마우스를 올려, 타입스크립트 언어 서비스를 통해 간단히 클래스 객체로 변환할 수 있다.
var 대신 let/const 사용하기
for 대신 for-of 또는 배열 메서드 사용하기
함수 표현식보다 화살표 함수 사용하기
class Foo {
method() {
console.log(this);
[1, 2].forEach(function(i) {
console.log(this);
});
}
}
const f = new Foo();
f.method();
// Foo, undefined, undefined in strict mode
// Foo, window, window (!) in non-strict mode
class Foo {
method() {
console.log(this);
[1, 2].forEach(i => {
console.log(this);
});
}
}
const f = new Foo();
f.method();
// Always prints Foo, Foo, Foo
컴파일러 옵션에 noImplicitThis(또는 strict)를 설정하면, 타입스크립트가 this 바인딩 관련오류를 표시해준다.
단축 객체 표현과 구조 분해 할당 사용하기
단축 객체 표현 사용const x = 1, y = 2, z = 3;
const pt = {
x, y, z,
};
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 = 10) {
return parseInt(str, base);
}
코드가 간결해질 뿐만 아니라 base가 선택적 매개변수라는 것을 나타낼 수 있다. 또한 타입 추론도 가능해진다.
저수준 프로미스나 콜백 대신 async/await 사용하기
연관 배열에 객체 대신 Map과 Set 사용하기
인덱스 시그니처는 편리하지만 몇 가지 문제가 있다. 특정 문자열이 주어질 때, 원치 않는 값과 타입을 받을 수 있기 때문에, 이런 문제를 방지하기 위해 Map을 사용하는 것이 좋다.
ex) 문자열이 constructor일 때
function countWordMap(text: string) {
const counts = new Map<string, number>()
for (const word of text.split(/[\s,.]+/)) {
counts.set(word, 1 + (counts.get(word) || 0))
}
return counts
}
타입스크립트에 use strict 넣지 않기
타입스크립트에서 수행되는 안전성 검사가 엄격 모드보다 더 엄격한 체크를 하기 때문에, use strict는 무의미하다.
TC39의 깃헙 저장소와 타입스크립트의 릴리스 노트를 통해 최신 기능을 확인할 수 있다.@ts-check 지시자를 사용하면 타입스크립트 전환시에 어떤 문제가 발생하는지 미리 알 수 있다. 하지만 이 지시자는 매우 느슨한 수준으로 타입 체크를 수행하고, 심지어 noImplicitAny 설정을 해제한 것보다 헐거운 체크를 수행한다.
사용법
// @ts-check
const person = {first: 'Grace', last: 'Hopper'};
person.first * 2 // Error
// 산술 연산 오른쪽은 'any', 'number' 'bigInt' 또는 열거형이여야 합니다.
위처럼 간단 오류 외에도 선언되지 않은 전역 변수, 알 수 없는 라이브러리 등에서 사용이 가능하다.
JSDoc 주석을 이용하면 자바스크립트 상태에서도 타입 단언과 추론이 가능하다.
타입스크립트는
.ts파일에서 가장 잘 동작하며 마이그레이션의 궁극적인 목표는 모든 코드가 타입스크립트 기반으로 전환되는 것이다.
대규모 프로젝트 경우에는 한꺼번에 마이그레이션 하는 것이 불가능하므로 점진적으로 전환할 수 있어야 한다.
그 기간 중에 자바스크립트와 타입스크립트가 동시에 동작할 수 있도록 해야하는데 그 방법의 핵심이 allowJs 컴파일러 옵션이다.
allowJs옵션은 타입스크립트 파일과 자바스크립트 파일을 서로 임포트 할 수 있게 해준다.
빌드 체인을 직접 구성했다면 복잡한 작업이 필요할텐데 한 가지 방책으로 outDir 옵션을 사용할 수 있다.
outDir옵션 사용 시 타입스크립트가outDir에 지정된 디렉토리에 소스 디렉터리와 비슷한 구조로 자바스크립트 코드를 생성하고 지정된 디렉터리를 대상으로 기존 빌드 체인을 실행하면 된다.
allowJs 컴파일러 옵션을 사용하자.다른 모듈에 의존하지 않는 최하단 모듈부터 작업을 시작해서 의존성 최상단에 있는 모듈을 마지막으로 완성하자.
서드파티 라이브러리
외부 API
두 개 모두 프로젝트 내의 모듈에 의존하지 않기 때문에 먼저 해결하는 것이 좋다.
마이그레이션할 때는 타입 정보 추가만 하고, 리팩터링을 하지 말자. 당장의 목표는 코드 개선이 아니라 타입스크립트로 전환하는 것이다.
마이그레이션 중 발생할 수 있는 오류는 다음과 같다.
선언되지 않은 클래스 멤버
타입이 바뀌는 값
const state = {};
state.name = 'New York' //js일 때는 ok
// error '{}' 유형에 'name' 속성이 없습니다.
JSDoc 타입 정보를 타입스크립트 타입으로 전환해 주는 빠른 수정 기능이 있다.
자바스크립트 상태에서 JSDoc과 @ts-check를 사용한 상태라면 타입스크립트로 전환하는 순간 타입 정보가 무효화 된다는 것을 주의하자.
마지막 단계로, 테스트 코드를 타입스크립트로 전환하면 된다. 로직 코드가 테스트 코드에 의존하지 않기 때문에, 항상 의존성 관계도의 최상단에 위치한다.
noImplicitAny가 설정되지 않은 상태에서는 타입 선언에서 비롯되는 실제 오류가 숨어있기 때문에 마이그레이션이 완료되었다고 할 수 없다.
noImplicitAny 설정을 활성화하여 마이그레이션의 마지막 단계를 진행하자. 그래야 타입 선언과 관련된 실제 오류가 보여진다.noImplicitAny를 전면 적용하기 전에 로컬에서부터 타입 오류를 점진적으로 수정하자.최종적으로 가장 강력한 설정은
strict: true이다. 타입스크립트에 익숙해진 다음 조금씩 타입 체크 강도를 높여가자.