본문 바로가기

웹 개발/Frontend

TypeScript) 타입스크립트 기초

이 글을 아래 링크를 참고하여 공부하며 정리한 자료입니다. https://www.samsungsds.com/kr/insights/TypeScript.html

 

활용도가 높아지는 웹 프론트엔드 언어, 타입스크립트(TypeScript)

활용도가 높아지는 웹 프론트엔드 언어, 타입스크립트(TypeScript)

www.samsungsds.com


타입스크립트란?

자바스크립트를 기반으로 정적 타입 문법을 추가한 프로그래밍 언어 

 

타입스크립트의 특징

  • 타입스크립트 : 정적 타입 컴파일 언어 -> 컴파일러 또는 바벨로 자바스크립트 코드로 변환되어 코드 작성 단계에서 오류 확인 가능하여 버그를 사전에 제거할 수 있고, 실행 속도가 매우 빠르다  (자바스크립트 : 동적 타입 인터프리터 언어 -> 런타임에 오류 발견 가능)
  • 자바스크립트의 슈퍼셋 : 자바스크립트 기본 문법에 타입스크립트 문법을 추가한 것으로 자바스크립트 코드를 타입스크립트로 컴파일해서 변환할 수 있다. 즉, 자바스크립트 코드가 100% 호환되어 프로젝트의 자바스크립트 코드를 점진적으로 전환하며 계속 사용할 수 있는 것 ! (js 사용 가능하다 = ts 도 사용가능하다) 
  • 객체 지향 프로그래밍 지원 : 클래스, 인터페이스, 상속, 모듈 등과 같은 패턴을 제공
  • 오래되지 않았지만 인기가 많은 언어이기 때문에 다양한 라이브러리, 에디터가 이 언어 관련 기능과 플러그인을 지원한다. 특히! VSCode에서도 지원!!
  • 단점 : 코드 작성시 타입을 결정해야 해서 번거롭고 가독성이 떨어지며 코드량이 증가한다
  • 프로젝트 규모가 크고 복잡하여 유지보수가 중요한 장기 프로젝트일수록 타입스크립 사용 이점이 부각됨 (즉, 유지보수성을 높다) 

 

타입스크립트로 전환하기 

  • 유효한 자바스크립트라면 유효한 타입스크립트이기 떄문에 점진적으로 전환 가능 
  • VSCode로 자바스크립트 페어링
    • 자바스크립트에서 타입스크립트 검사 활성화 설정 켜기 
    • .vscdoe/setting.json 
      {
        "Javascript.implicitProjectConfig.checkJs": true
      }​
    • 타입이 안전하지 않은 라인에 에디터상에서만 에러 표시됨 
    • 선택적 비활성화
      @ts-ignore - 해당 줄
      @ts-nocheck - 전체​
  • 자바스크립트용 타입스크립트 컴파일러 사용
    • tsconfig.json
      {
       "compilerOptions": {
        "allowJs": true // 타입스크립트 컴파일러로 실행할 자바스크립트 파일 선택 
        "checkJs": false  // 자바스크립트 파일에 대한 타입 체크 
        "outDir": "./dist"
        "rootDir": "./src"
        "strict": false
       }
      }
  • 자바스크립트 파일을 타입스크립트 파일로 변환 (.js -> .ts)  with allowJs (js파일에 대한 타입 체크를 하게 해놔서 점진적으로 전환 가능) 
  • 타입체크를 엄격하게 하는 옵션들을 하나씩 활성화해가면서 전환 
    {
     "compilerOptions": {
     "noImplicitAny": true,
     "strictNullChecks": true,
     "strictFunctionTypes": true,
     "strictBindCallApply": true,
     "strictPropertyInitialization": true,
     "noImplicitThis": true,
     "alwaysStrict": true
    }​

타입스크립트 기본 문법 

  • 기본 타입
    Boolean, Number, String, Object, Array, Tuple, Enum, Any, Void, Null, Undefined, Never
    • Tuple : 배열의 타입 순서와 배열 길이를 지정할 수 있는 타입 
      var arr: [string, number] = ['aa', 100];
      
      // var <변수이름>: [배열 요소들의 타입 리스트] = [타입 리스트와 일치하는 배열 요소들]

    •  Enum : 정수 또는 문자열 값 집합에 고정된 이름을 부여할 수 있는 타입으로, 값의 종류가 일정한 범위로 정해져 있는 경유 유용하다. 디폴트로 0부터 시작하며 1씩 증가
      enum Shoes {
       Nike = '나이키',
       Adidas= '아디다스'
      }
      
      
      // enum <집합이름> { <값이름> = <값>, ... }​
    • Any : 모든 데이터타입 허용 , 이게 있기 때문에 js 파일에 타입이 없어도 허용되는건가?
    • Void : undefined또는 null만 할당 가능한 타입, 함수에 리턴 값 없는 경우
  • 변수에 타입 설정 예시
    let str: string = 'hi';
    let num: number = 100;
    
    let arr: Array = [1, 2, 3];
    let arr2: number[] = [1, 2, 3];
    
    let obj: object = {};
    let obj2: { name: string, age: number} = {
     name: 'hoho',
     age: 22
    };
    
    
    // let <변수이름>: <타입> = <값>;
  • 함수 인자에 타입 설정 예시
    function add(a: number, b: number): number {
    	return a+b;
    }
    //옵셔널 파라미터
    function log(a: string, b?: string, c?: string) {
     console.log(a);
    }​
  • 인터페이스 : 타입을 정의한 규칙 
    interface User {
     age: number;
     name: string;
    }
    
    // User 객체 규칙을 정의해두고 User 객체 생성해서 사용 가능
    
    var person: User = {
     age: 30,
     name: 'aa'
    }
    
    function getUser(user: User) {
     console.log(user);
    }
    
    
    // example
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    function greeter(person: Person) {
        return "Hello, " + person.firstName + " " + person.lastName;
    }
    
    let user = { firstName: "Jane", lastName: "User" };
    
    document.body.textContent = greeter(user);
  • 인덱싱 
    interface StringArray {
     [index: number]: string;
    }
    
    var arr2: StringArray = ['a', 'b', 'c'];
    arr[0] = 10 
    // 인덱스는 정수를 사용하지만 배열의 요소는 문자열이라고 정의했기 때문에 
    // StringArray 객체인 arr의 첫번째 요소에 10 (정수) 할당 불가​
  • 딕셔너리 패턴 
    interface StringRegexDictionary {
     [key: string]: RegExp
    }
    
    var obj: StringRegexDictionary = {
     cssFile: /\.css$/,
     jsFile: 'a' //Error
    }
    
    // obj라는 변수는 문자열-정규식 딕셔너리 패턴을 사용, 즉, 키가 문자열, 밸류가 정규식인 객체 
    
    obj['cssFile'] = /\.css$/;
    obj['jsFile'] = 'a' //Error // 밸류는 정규식이어야 하기 때문에 문자열을 할당하면 에러!​
  • 인터페이스 확장 
    interface Person{
     name: string;
     age: number;
    }
    
    // Person 인터페이스를 상속해서 그대로 사용하면서 또 다른 속성을 추가한 User 
    interface User extends Person{
     language: string;
    }​
  • 오퍼레이터 
    • Union = OR 
      // Developer2의 속성과 Person의 속성만을 가졌다면 someone이 될 수 있음
      // Person은 없는 속성이지만 Developer2가 가진 속성을 가졌어도 someone이 될 수 있음 
      function askSomeone(someone: Developer2 | Person) {
       console.log(someone);
      }​
    • Intersection = AND 
      // Developer 속성과 Person 속성중 겹치는 것만 가지고 있는 객체만 someone이 될 수 있음 
      function askSomeone(someone: Developer & Person) {
       console.log(someone);
      }​
    • Generic : 여러 가지 타입을 받을 수 있음 
      // text 라는 제네릭 타입이 인자을 인자로 받아서 그 타입을 그대로 리턴하는 함수 
      function logText(text: T):T {
       return text;
      }
      
      logText<string>('aa');
      logText<number>(100);​
  • 타입 추론 = 타입스크립트가 코드를 해석하는 과정 
    • Boolean을 할당했다가 정수 또는 문자열 등 다른 타입을 할당할 수 없다.
    • Best Common type : 배열에 여러개의 타입이 담겨 있다면 Union으로 묶어나간다. 예를 들어 배열에 정수와 Boolean 값이 같이 있다면 타입스크립트는 이 배열의 타입을 Number|Boolean으로 정의한다. 
  • 타입 단언 = 타입스크립트 해석보다 확실한 목적이 있을 경우, 개발자가 해당 코드에 타입을 직접 지정하는 것 
    var a;
    a = 10;
    a = 'string';
    var b = a as string;
    
    
    var div = document.querySelector('div') as HTMLDivElement;
    div.innerText;​
  • 타입 호환 = 특정 타입이 다른 타입에 잘 호환되는지 
    • 구조적 타이핑 : 코드 구조 관점에서 타입이 호환되는지 판단하는 것, 구조적으로 더 큰 타입은 작은 타입으로 호환될 수 없지만 반대로 작은 타입은 큰 타입으로 호환됨 
    • 아래와 같은 경우 Developer가 Person보다 구조적으로 더 큰 타입이기 때문에 Person으로 호환될 수 없으나 Person은 Developer로 호환될 수 있다
      interface Developer {
       name: string;
       age: string;
      }
      interface Person {
       name: string;
      }
      
      var developer: Developer;
      var person: Person;
      
      developer = person; //Error
      person = developer;​

References