* 타입스크립트 강의-02 링크

[클래스]

  • 프로토타입 - 자바스크립트 내용
  var user = { name : 'capt', age : 100};
  // var admin = { name : 'capt', age : 100, role : 'admin'};
  var admin = {};

  admin.__propto__ = user; // 프로토타입을 설정

  admin.name // 'capt'
  admin.age // 100

  admin.role = 'admin';

  // 이렇게 하면 위와 같이 사용할 수 있다.


  var obj = {a: 10}; // Object 메서드 사용할 수 있음.
  Object.keys(obj);
  obj.hasOwnProperty('a');

  var arr = []; // Array 메서드 사용할 수 있음.

[제네릭]

타입스크립트 시작하는 사람들의 가장 두려워하는 문법.

  function logText(text: string) {
    console.log(text);
    text.split('').reverse().join('');
    return text;
  }

  function logNumber(num: number){
    console.log(num);
    return num;
  }

  logText('a');
  logNumber(10);

위와 같은 경우

  function logText<T>(text: T):T{
    console.log(text);
    return text;
  }
  
  // T : string 매칭이 되어 string 형으로 결정 됨.
  logText<string>('하이');

이렇게 바꿀 수 있다.

  • Union과의 차이점 1) 유니온에서는
    function logText(text: string | number) {
      console.log(text);
      return text;
    }
        
    const a = logText('a');
    a.split('');//에러가 뜸. 보장된 형이 split이 제공되지 않기 때문임.
    logText(10);
    

2) 제네릭에서는

  function logText<T>(text: T):T{
    console.log(text);
    return text;
  }
  
  const str = logText<string>('abc');
  str.split('') // 에러 안뜸. (string으로 지정이 됨!)
  const login = logText<boolean>(true);
  • 인터페이스에 제네릭을 선언하는 방법 ``` typescript // interface Dropdown{ // value: string; // selected: boolean; // }

// const obj : Dropdown = {value: ‘abc’, selected: false};

interface Dropdown{ value: T; selected : boolean }

const obj: Dropdown = {value: 'abc', selected: false}

  
  - 제네릭의 타입 제한

  ```typescript
    function logTextLength<T>(text: T[]): T[] {
      console.log(text.length);
      text.forEach(function (text){
        console.log(text);
      });
      return text;
    }

    logTextLength<string>(['hi', 'abc']);
    'abc'.length;
  • 제네릭 타입 제한 2 - 정의된 타입 이용하기.
    interface LengthType {
      length: number;
    }
      
      
    function logTextLength<T extends LengthType>(text: T):T {
      text.length;
      return text;
    }
    // logTextLength(10); // 에러남.
    logTextLength({length: 10});
    
  • 제네릭 타입 제한 3 - keyof
    interface ShoppingItem{
      name: string;
      price: number;
      stock: number;
    }
        
    // keyof : 인터페이스의 키 값중에 하나를 가져온다.
    function getShoppingItemOption<T extends keyof ShoppingItem>(itemOption: T):T{
      return itemOption;
    }
        
    // getShoppingItemOption(10);
    // getShoppingItemOption<string>('a');
    getShoppingItemOption("name");
    

[프로젝트2]

Promise 의 제네릭. Promise의 반환 값의 형을 제네릭으로 지정해주면 된다.

[타입추론]

이게 어떤 타입이냐 하는 것을 추론해나가는 방법. var a하고 a 위에 마우스 갔다 대면 any라고 한다.(vscode ts 내장 서버)

  // 타입추론 기본 1
  var a = 10; // number
  var b = 'abc' // string


  function getB(b){ // any
    return b; // any
  }

  function getC(c = 10){ // number
    var d = 'hi'; // stirng

    return d + c; // number + string : string
  }
  // 타입 추론 기본2
   interface Dropdown1<T> {
     value : T;
     title : string;
   }

  // 변수 형에 따라서 초기화 
   var shoppingItem: Dropdown1<string> = {
     value : 'item 1',
     title : 'title 1'
   }
  // 타입추론 기본3
    interface Dropdown1<T> {
      value : T;
      title : string;
    }
    
    interface DetailedDropdown<K> extends Dropdown1<K>{
      description: string;
      tag: K;
    }

    // 변수 형에 따라서 초기화 
    var shoppingItem: DetailedDropdown<string> = { 
      title : 'title 1',
      description : 'ab',
      value: 'yes!',
      tag:'t'
    }

    // Best Common Type : 지가 알아서 찾아간ㄷ.
    var arr = [1,2,true, 'a'];
    - Best Common Type
    var arr = [1,2,true];
    
    var arr: (number | boolean)[]
  • Tpye Script Language Server
    결론적으로는 내부적으로 도는 서버가 있다

[타입 단언]

[타입 가드]

[타입스크립트 모듈]

[유틸리티 타입]

  • Partial : 인터페이스 안에 타입 몇개만 사용하겠다. 변형해서 쓰고 싶을 때 사용
  • Pick : 인터페이스 안의 타입 중에 몇개를 뽑아서 사용하겠다.
  • Omit : 인터페이스 안에서 몇개를 제외시키겠다. 더 많은 유틸리티 타입 레퍼런스는 타입스크립트 핸드북에서 확인합시다.

[맵드 타입]

기존에 정의되어 있는 타입을 새로운 타입으로 변환해주는 문법. 자바스크립트 map map 함수를 돌려서 새로운 타입을 뽑아낸다.

{ [ P in K ] : T} 이런식으로 쓰면 된다.

[JS에 TS를 적용할 때 주의할점]

  1. 기능 변경은 하지 말 것.
  2. 테스트 커버리지가 낮을 땐 함부로 타입스크립트 전환하지 말 것.
  3. 처음부터 타입을 엄격하게 적용하지 말 것. string 말고 any로 적용한다든지.. (일단은)

[바꾸기]

※ 기존 자바스크립트 소스를 타입스크립트로 바꾸는 과정 그냥 아예 새로운 타입스크립트 프로젝트를 만들어서 그 안에 로직을 가져온다.

1. 타입스크립트 기본 환경 구성

  • NPM 초기화
  • 타입스크립트 라이브러리 설치
  • 타입스크립트 설정 파일 생성 및 기본 값 추가
  • 자바스크립트 파일을 타입스크립트 파일로 변환
  • tsc 로 타입스크립트 컴파일하기

2. 하나씩 바꾸기

  • 외부 라이브러리 참조 (tsconfig.json 파일 설정)

3. 엄격하지 않은 타입 환경(loose type)에서 프로젝트 돌려보기

  • 프로젝트에 테스트 코드가 있다면 테스트 코드가 통과하는지 먼저 확인
  • 프로젝트 js 파일을 모두 ts파일로 변경
  • 타입스크립트 컴파일 에러가 나는 것 위주로만 먼저 에러가 나지 않게 수정
    여기서 기능을 사소하게라도 변경하지 않도록 주의
  • 테스트 코드가 잘 돌아가는지 확인.

4. 명시적인 any 선언하기

  • tsconfig.json 파일에 noImplicitAny 값을 true로 추가.
  • 가능한한 구체적인 타입으로 타입 정의

5. 프로젝트 환경 성

[Babel]

브라우저 버전 호환할 때 쓰는 애들

예를들어

  const sum = (a  , b) => {
    return a+b;
  }

이렇게 입력하면

  "use strict";

  const sum = (a, b) => {
    return a + b;
  };

이렇게 바꿔줌

[ESLint]

자바스크립트 코드에서 문제 찾고 고치는 코드.

  var sum=(a,b)=>a+b;

이런 코드를

  var sum = ( a, b ) => a + b;

이런식으로 바꿔줌.

ESLintRC
  • prettier rule print width 넓이

      //.eslint.js
      rules: {
        'prettier/prettier': [
          'error',
          {
            singleQuote: true,
            semi: true,
            useTabs: false,
            tabWidth: 2,
            printWidth: 80,
            bracketSpacing: true,
            arrowParens: 'avoid',
            endOfLine: 'auto',
          },
        ],
      },
    

    prettier 플러그인이 package.json 안에 있어야 함. eslint가 돌면서 settings.json안의 editor.codeActionOnSave 안에 source.fixAll.eslint 의 true설정을 읽어와서 동작 함

    .eslintignore 안에 넣어두면 해당 파일은 적용 안되게 만들 수 있음.

    TSLint를 안쓰고, ESLint를 사용한 이유 MS사에서 사용하다보니, ESLint가 더 좋은 성능을 내었기 때문

[외부라이브러리 모듈화]

가장 대표적인 에러 같은 경우는 외부라이브러리 모듈화가 필요한 부분임.

  <!-- index.html -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>

위 소스를 ts파일에서 읽어올 수 있어야 함.

npm install로 설치 후에 import 시키면 됨

  //app.ts
  // 라이브러리 로딩
  import 변수명 from '라이브러리 이름'
  import axios from 'axios'; // 이러면 에러가 많이 해결 됨. (잘 만들어진 라이브러리이기 때문에)
  // 얘는 에러남. (typescript 지원이 안되었기 때문 - 지금 최신 버전은 메이저 업데이트가 되어 사용가능 )
  import Chart from 'chart.js'; 

  // 이렇게 사용해야 한다고 함. 별건 없음 (stack overflow 뒤졌다 함)
  import { Chart } from 'chart.js';



  // 변수, 함수 임포트 문법
  import {} from '파일 상대 경로';

Definitely Typed 에 대하여

@tpyes/chart.js 이런식으로 된게 타입스크립트로 저장 된 애임. 얘를 깔아야 ts에서 지원이 됨.

types라고 하는 애가 없을 때,

tsconfig.json 에서 아래와 같이 수정

  "typeRoots": ["./node_modules/@types", "types"]

임의로 project/types/chart.js -> index.d.ts

  declare module 'chart.js';

위와 같이 추가한다.

API 반환 타입

// 개발자도구 네트워크 부분에서 가져옴,
interface CovidSummaryResponse {
  Countries: any[];
  Date: string;
  Global: any;
  Message: string;
  // NewConfirmed: 1791655;
  // NewDeaths: 5209;
  // NewRecovered: 0;
  // TotalConfirmed: 560298445;
  // TotalDeaths: 6363126;
  // TotalRecovered: 0;
  // ID: '712e424f-5fb9-4839-96a4-1fa045df797d';
}


function fetchCovidSummary(): Promise<AxiosResponse<CovidSummaryResponse>> {
  const url = 'https://api.covid19api.com/summary';
  return axios.get(url);
}

// 위와 같이 지정해두면 interface 타입들을 가져와서 자동완성에 사용할 수 있음.; (아래와 같이)
fetchCovidSummary().then(res => res.data.Countries)

6.strict 옵션 적용

// tsconfig.json
    "strict": true

위 속성 추가 => app.ts 에러 마구 뜸

조금 더 안전하게 코딩을 할 수 있음 실질적으로 쓰게 되는 속성은 strictNullCheck 옵션

객체?.요소 -> 옵셔널 체이닝 객체!.요소 -> 객체는 null이 절대 아님을 정하는 것. (타입단언)

타입단언시 주의해야 할 점.

//타입 어썰션 : 으로 할당
interface Hero {
  name: string;
  skill : string;
}

const capt : Hero ={
  name : 'capt',
  skill : 'shield',
};

const capt: Hero {};
const capt : {} as Hero;
capt.name = 'capt';
capt.skill= 'shield';

const a: string|null;
// non null type assertion 
a!