Search

7주차

6장 타입 선언과 @types

45. devDependencies에 typescript와 @types 추가하기

dependencies : 런타임에 사용하는 코드
devDependencies : 개발 및 테스트에는 사용되지만, 런타임에는 필요없는 코드
peerDependencies : 실제로 패키지에서 직접 require(import)하지 않더라도 호환성이 필요한 경우 명시해줍니다. Library를 사용하는 사용자에게 버전을 맞춰야하는 것들을 명시해주고, 이에따라 warning이 뜨거나, 설치에서 에러가 발생합니다.
프로젝트 별로 다른 버전의 타입스크립트를 사용하므로, 시스템 레벨에 설치하면 안됩니다.
@types는 devDependencies에 추가해줘야 합니다.

46. 타입 선언과 관련된 세 가지 버전 이해하기

@types, 라이브러리 버전, ts 버전 3가지를 고려해야합니다.
라이브러리와 타입버전이 개별관리되는 방식은 4가지 문제가 있습니다.
라이브러리 버전 > 타입 버전
타입 선언을 업데이트 해줍니다.
해당 사항이 아직 업데이트 되지 않았다면, 보강 기법을 활용하여, 에러가 발생하는 타입을 프로젝트 자체에 추가합니다.
라이브러리 버전 < 타입 버전
라이브러리를 올리거나, 타입을 내리기
프로젝트 TS 버전 < 라이브러리 TS 버전
버전을 조정해줍니다.
declare module 선언으로 라이브러리의 타입 정보를 없애는 것도 방법입니다.
@types 의존성이 라이브러리간에 충돌할 수 있습니다.
npm ls @types/foo 를 통해서 타입 선언 중복 추척해 해결해줄 수 있습니다.
types: index.d.ts 와 같은 번들링에 타입선언을 포함하는 방식에는 4가지 문제점이 있습니다.
타입버전을 따로 컨트롤할 수 없어 ts 버전이 올라가며 에러가 발생할 수 있습니다.
보통 의존성은 devDependencies에 들어가는데 다른 사용자는 해당을 설치하지 않게되어 에러가 발생할 수 있습니다.
프로젝트 과거 버전에 문제가 있는 경우 과거버전으로가서 패치 업데이트를 해야합니다.
타입 선언의 패치업데이트를 자주하기 어렵습니다.

47. 공개 API에 등장하는 모든 타입을 익스포트하기

어차피 사용자가 필요하다면 타입 추출이 가능하므로, 숨기려드는 것을 필요없는 행동입니다.

48. API 주석에 TSDoc 사용하기

편집기가 처리해줘 JSDoc/TSDoc 사용이 좋습니다.

49. 콜백에서 this에 대한 타입 제공하기

class C { vals = [1, 2, 3]; logSquares() { for(const val of this.vals) { console.log(val * val); } } } const c = new C(); c.logSquares(); // 1 4 9 const c = new C(); const method = c.logSquares; method(); // Uncaught TypeError: Cannot read properties of undefined (reading 'vals')
JavaScript
복사
logSquares를 참조 변수로 사용하므로 this의 값은 undefined로 설정되어 에러가 발생합니다.
이를 해결하기 위해 call을 사용해서 해결할 수 있습니다.
이런 다양한 this의 문제가 발생할 수 있기 때문에 원리를 이해해야 하고, 콜백 함수에서 this 사용시 타입정보를 명시해줘야합니다.

50. 오버로딩 타입보다는 조건부 타입을 사용하기

function double(x) { return x + x; } // 모호합니다. function double(x: number|string): number|string; // 과하게 구체적입니다. // T를 'x'로 하게될 시 결과는 'xx'여야하는데 'x'라고 명시중입니다. function double<T extends number|string>(x: T): T; // 타입이 조금은 명확해졌습니다만 버그가 있습니다. function double(x: number): number; function double(x: string): string; function f(x: number|string){ double(x); // 'string|number' 인수는 'string' 형식의 매개변수에 할당할 수 없습니다. } // 조건부 타입이 가장 좋은 해결책입니다. function double<T extends number | string>(x: T): T extends string ? string : number;
JavaScript
복사

51. 의존성 분리를 위해 미러 타입 사용하기

@types/node속 Buffer와 같은 사용자에 따라 불필요한 경우 구조적 타이핑을 사용해주면 됩니다.

52. 테스팅 타입의 함정에 주의하기

타입을 테스트할 때는 함수 타입의 동일성과 할당 가능성의 차이점을 알고있어야합니다.
const lengths: number[] = map(['join', 'paul'], name => name.length);
JavaScript
복사
테스트를 위해 할당을 하는 방법에는 2가지 문제가 있습니다.
불필요한 변수
두 타입이 동일한지 체크하는 것이 아닌 할당 가능성만을 체크
객체의 추가적인 속성 등을 체크하지 않고, 매개변수의 타입선언 갯수와 함수간 실제 사용의 일치를 고려하지 않습니다.
const double = (x: number) => x * 2; assertType<(a: number, b: number) => number>(double); // 에러 x
JavaScript
복사
콜백이 있는 함수를 테스트 할때는 콜백 매개변수의 추론된 타입을 체크해야하고, thisrㅏ 있다면 테스트해줘야합니다.
declare module과 같은 any를 주의해야합니다.

7장 코드를 작성하고 실행하기

53. 타입스크립트 기능보다는 ECMAScript 기능을 사용하기

열거형, 매개변수 속성, 트리플 슬래시 임포트, 데코레이터는 타입 정보를 제거한다고 JS가 되지 않기때문에 사용을 피하는 것이 좋습니다.

54. 객체를 순회하는 노하우

const obj = { one: 'uno', two: 'dos', three: 'tres' }; for (const k in obj) { const v = obj[k]; // k는 string으로 추론됩니다. } // 해결법 let k: keyof typeof obj; for (const k in obj) { const v = obj[k]; }
JavaScript
복사
interface ABC { a: string; b: string; c: number; } function foo(abc: ABC){ for (const k in abc) { const v = abc[k]; // k: string } } // foo 함수는 ABC 타입에 할당 가능한 어떤 값이든 매개변수로 허용하기 때문에 d가 가능합니다. // 따라서 할당 가능한 객체의 key 값은 string으로 인식하게됩니다. const x = {a: 'a', b: 'b', c: 2, d: new Date()); foo(x); // 정상
JavaScript
복사
// 타입 에러 상관없이 사용하려면 Object.entires를 사용하면 됩니다. ... for(const [k, v] of Object.entries(abc))
JavaScript
복사
키값을 정확히 파악하고 있다면 keyof T와 for-in을 사용하고, 일반적으론 Object.entries를 사용합니다.

55. DOM 계층 구조 이해하기

EventTarget은 DOM 타입 중 가장 추상화된 타입입니다. 이벤트 리스터 추가, 제거, 보내기 밖에 할 수 없습니다.
Node는 텍스트와 주석을 포함하고 있습니다.
Element는 HTMLElement와 SVGElement를 포함합니다.
HTMLxxxxElement는 각자 고유한 속성을 가지고 있습니다.
DOM querySelector등의 경우엔 사용자가 더 잘 알고 있는 경우가 많아 단언이나 if 분기를 처리해주면 됩니다.

56. 정보를 감추는 목적으로 private를 사용하지 않기

public, protected, private는 TS에서만 강제되고 런타임에선 소용이 없으므로 데이터를 감추고 싶다면 클로저를 사용해야합니다.

57. 소스맵을 사용하여 타입스크립트 디버깅하기

sourcemap 컴파일 옵션을 통해 디버깅을하고, 공개되지 않도록 확인해야합니다.

8장 타입스크립트로 마이그레이션하기

58. 모던 자바스크립트로 작성하기

ECMAScript 모듈을 사용하세요
프로토타입 대신 클래스를 사용하세요.
var 대신 let/const 사용하기
for(;;) 대신 for-of 또는 배열 메서드 사용하기
함수 표현식보단 화살표 함수 사용하기단축 객체 표현과 구조 분해 할당 사용하기
함수 매개변수 기본값 사용하기
저수준 프로미스나 콜백 대신 async/await 사용하기
연관 배열에 객체 대신 Map과 Set 사용하기
타입스크립트에 use strict 넣지 않기

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

//@ts-check를 상단에 추가시 js도 타입체크를 할 수 있습니다.
전역변수로 인해 문제 발생시 선언 파일을 추가해주면 됩니다.
// @ts-check /// <reference path="./types.d.ts" />
JavaScript
복사
DOM 관련 에러는 JSDoc을 사용해 타입 단언을 대체할 수 있습니다.
// @ts-check const ageEl = /** @type {HTMLInputElement} */)document.getElementById('age'));
JavaScript
복사

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

기존의 빌드 방식에 TS 컴파일러는 추가하기 위해선는 allowJs 옵션이 필요합니다.

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

최우선적으로 서드파티 모듈과 외부 API 호출에 대해 @types 를 추가해줘야합니다.
의존성 최하단부터 위로 올라가며 작업을 진행합니다.
JSDoc 주석을 활용해줍시다.

62. 마이그레이션의 완성을 위해 noImplicityAny

작업 중 임시로 any로 대체해둔 경우가 많으므로 noImplicityAny 옵션을 통해 any들을 제거해줍니다.