|
| 1 | +# 타입스크립트 도입 전에 @ts-check와 JSDoc으로 시험해 보기 |
| 2 | + |
| 3 | +- @ts-check 지시자를 사용하면 타입스크립트 전환시에 어떤 문제가 발생하는지 미리 볼 수 있다. |
| 4 | +- @ts-check 지시자는 느슨한 수준으로 타입체크를 수행한다 (noImpllicitAny 설정을 해제한 것보다 헐거운 체크를 수행함) |
| 5 | +- noImplicitAny 는 컴파일러 옵션 중 하나로, 암시적 any를 허용하지 않도록 설정하는 옵션이다. |
| 6 | + |
| 7 | +### ts-check 지시자 사용하기 |
| 8 | + |
| 9 | +아래는 @ts-check 지시자를 사용해서 자바스크립트에도 불가하고 타입 체크가 동작한다. |
| 10 | + |
| 11 | +```ts |
| 12 | +const person = { first: "Grace", last: "Hopper" }; |
| 13 | +2 * person.first; |
| 14 | +// ~~~~~~~~~~~~ |
| 15 | +``` |
| 16 | + |
| 17 | +person.first의 타입은 string 으로 추론됨. |
| 18 | +따라서 2 \* person.first 에는 타입 불일치 오류가 발생한다. |
| 19 | + |
| 20 | +### 선언되지 않은 지역변수 |
| 21 | + |
| 22 | +어딘가에 숨어있는 변수라면, 변수를 제대로 인식할 수 있게 별도로 타입선언 파일을 만들어야 한다. |
| 23 | + |
| 24 | +```ts |
| 25 | +// @ts-check |
| 26 | +console.log(user.firstName); |
| 27 | +// ~~~~ Cannot find name 'user' |
| 28 | +``` |
| 29 | + |
| 30 | +user 을 찾을 수 없어 오류가 발생하고 있다. 아래에서 user 을 선언하여 오류를 해결한다. |
| 31 | + |
| 32 | +```ts |
| 33 | +interface UserData { |
| 34 | + firstName: string; |
| 35 | + lastName: string; |
| 36 | +} |
| 37 | +declare let user: UserData; |
| 38 | +``` |
| 39 | + |
| 40 | +### 알 수 없는 라이브러리 |
| 41 | + |
| 42 | +서드파티 라이브러리 (예 : jquery) 를 사용하는 경우, 서드파티 라이브러리의 타입 정보를 알아야 한다. |
| 43 | + |
| 44 | +```ts |
| 45 | +// @ts-check |
| 46 | +$("#graph").style({ width: "100px", height: "100px" }); |
| 47 | +// ~~~~~ Cannot find name '$' |
| 48 | +``` |
| 49 | + |
| 50 | +jquery 타입선언을 설치해 오류를 제거한다. |
| 51 | + |
| 52 | +``` |
| 53 | +$ npm install --save-dev @types/jquery |
| 54 | +``` |
| 55 | + |
| 56 | +이제 오류가 제이쿼리의 사양과 관련된 내용으로 변경된 것을 확인할 수 있다. |
| 57 | + |
| 58 | +```ts |
| 59 | +// @ts-check |
| 60 | +$("#graph").style({ width: "100px", height: "100px" }); |
| 61 | +// ~~~~~ Property 'style' does not exist on type 'JQuery<HTMLElement>' |
| 62 | +``` |
| 63 | + |
| 64 | +### 부정확한 JSDoc |
| 65 | + |
| 66 | +프로젝트에 이미 JSDoc 스타일의 주석을 사용중이었다면 @ts-check 지시자를 설정하는 순간부터 기존 주석에 타입 체크가 동작하게 되고 수많은 오류가 발생한다. |
| 67 | + |
| 68 | +```ts |
| 69 | +// @ts-check |
| 70 | +/** |
| 71 | + * Gets the size (in pixels) of an element. |
| 72 | + * @param {Node} el The element |
| 73 | + * @return {{w: number, h: number}} The size |
| 74 | + */ |
| 75 | +function getSize(el) { |
| 76 | + const bounds = el.getBoundingClientRect(); |
| 77 | + // ~~~~~~~~~~~~~~~~~~~~~ Property 'getBoundingClientRect' |
| 78 | + // does not exist on type 'Node' |
| 79 | + return { width: bounds.width, height: bounds.height }; |
| 80 | + // ~~~~~~~~~~~~~~~~~~~ Type '{ width: any; height: any; }' is not |
| 81 | + // assignable to type '{ w: number; h: number; }' |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +첫번째 오류 : DOM 타입 불일치 |
| 86 | + |
| 87 | +- getBoundingClientRect() 는 Node 가 아니라 Element 에 정의되어있기 때문 |
| 88 | + |
| 89 | +두번째 오류 : return 타입 불일치 |
| 90 | + |
| 91 | +- @return 타입에 명시된 타입과 실제 반환 타입이 맞지 않는다. |
| 92 | + |
| 93 | +타입스크립트 언어 서비스는 타입을 추론해서 JSDoc 을 자동으로 생성해준다. 자동생성기능은 타입 정보를 빠르게 추가할 수 있기 때문에 유용하지만 실제로 잘 동작하지 않는 경우도 있다. |
| 94 | + |
| 95 | +주석이 코드 분량을 늘려서 로직을 해석하는데 방해가 될 수 있기 때문에 @ts-check 지시자와 JSDoc 을 너무 장기간 사용하는 것은 좋지 않다. |
| 96 | + |
| 97 | +js -> ts 마이그레이션의 궁극적인 목표는 자바스크립트에 JSDoc 주석이 있는 형태가 아니라 모든 코드가 타입스크립트 기반으로 전환되는 것이다. |
0 commit comments