성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

Typescript

[TypeScript] 타입스크립트 기본기 다지기2

제이콥(JACOB) 2019. 12. 8. 22:15

Types

타입스크립트를 여러가지 타입을 같습니다(number, string, boolean...). 물론 앞에서도 약간의 언급과 함께 넘어갔지만, 이번에 좀 더 심화해서 살펴보겠습니다.

  • number 타입의 경우 hex, binary, octal 모두 가능합니다.
  • string 타입의 경우 큰 따옴표(", Double quotes), 작은 따옴표(', single quotes) 모두 가능 합니다. 또한 역따옴표(`, backtick)으로 깜싸져 있을 경우 멀티라인도 가능합니다.
  • Array 타입도 가능하며, 방법은 두 가지가 있습니다.
  const listA: number[] = [1, 2, 3];
  const listB: Array<number> = [1, 2, 3];

참고로 배열(array)타입의 요소로는 숫자 타입뿐만 아니라, 클래스나 인터페이스, 여러 내장 타입 등이 올 수 있습니다.

  • null, undefined 타입의 경우도 가능합니다. 대부분 다른 유형의 하위 유형으로 사용됩니다.
  let num: number | undefined = undefined;
  num = 123; // 가능

 

  • 문 리터럴 타입숫자 리터럴 타입 모두 가능합니다.
  let num: 1 | 2 | 3;
  num = 1; // 가능
  num = 4; // Error

  let str = '안녕' | '헬로우';
  str = '하이'; // Error

 

  • any 타입은 숫자, 문자, 함수도 가능하지만, 너무 많이 사용될 경우 typescript를 사용하는 의미가 없으므로 타입이 지정되지 않았거나 임시로 타입을 유지할 경우에 사용하시면 좋습니다.
  let result: any;
  result = 123;
  result = () => {};

 

Type assertions
any 타입과 자주 쓰이는 개념입니다. 한국어로 번역하기가 참 애매한데요. 그냥 타입 어써션이라고 하겠습니다(타입 재확인? 타입 표명? ...)
처음에는 any 타입으로 지정했다가 사용할 때 타입을 명확하게 알려주는 것을 뜻합니다. 이때 사용할 수 있는 방법은 2가지가 있습니다.

  let data: any;
  data = "Hello world";

  // 방법 1
  let dataLength1: number = (<string>data).length;

  // 방법 2
  let dataLength2: number = (data as string).length;

  console.log(dataLength1, dataLength2); // 11 11

결과 값은 같습니다. 편하신 걸로 사용하면 되지만 여기서 주의점이 있습니다.
만약 Typescript와 jsx를 같이 사용하신다면 반드시 방법2(~as) 로 하셔야 합니다.

  • object 타입도 가능하며, 앞에서 다뤘기 때문에 생략합니다.
  • enum 타입도 가능합니다(열거형 타입이라고도 합니다).
  enum Name { Jung, Kim, Pack }
  let firstName1: Name = Name.Jung; // 0
  let firstName2: string = Name[1]; // 'Kim'

열거형의 경우 0부터 시작하지만, 임의으로 변경할 수도 있습니다.

  enum Name { Jung = 2,
              Kim = 4,
              Pack = 3 }
  let firstName1: Name = Name.Jung; // 2
  let firstName2: string = Name[1]; // undefined
  let firstName3: string = Name[3]; // 'Pack'
  enum Name { Jung = 2,
              Kim,
              Pack }
  let firstName3: string = Name[3]; // 'Kim'
  • void 타입은 아무값도 반환하지 않는 함수의 타입을 정의한다.
  function exVoid(): void {
    console.log("return 되는 값네 없네요! 난 void 야");
  }
  console.log(exVoid, typeof exVoid); // undefined 'undefined'

여기서 한가지 생각해야 하는점은 반환값이 없을때는 void 타입으로 선언하지만, 반환 타입은 undefined이 할당된다는 점입니다. 따라서 void타입은 undefined타입과 null타입의 상위 타입이라, let exVoid() = null;이런식으로 할당할 수 있지만, 불필요한 선언이되므로 권장하지 않는 방법입니다.

tsconfig.json에서 컴파일 옵션을 줘서, 이런 불안정한 연산을 막을 수도 있습니다.

{
  "compilerOptions": {
    "strictNullChecks": true // null과 undefined 할당을 막음.
  }
}
  • naver 타입은 예외 타입으로 쓰이거나 절대 발생하지 않는 값(무한 루프)의 타입입니다.
  function exNaver1(): naver {
    throw new Error('난 naver로 지정해줘');
  }
  function exNaver2(message: string): naver {
    throw new Error(message);
  }
  function exNaver3(): naver {
    while(true){
      console.log('난 naver로 지정해줘');
    }
  }

 

Type alias

타입의 경우 별칭(Alias, 에일리어스 | 앨리어스) 설정이 가능합니다.

  type numOrStr = number | string;  
  let exNum: numOrStr;
  exNum = 5; // 가능
  exNum = "5"; //가능

타입 별칭의 경우 익명의 함수와 같이 쓸때 큰 힘을 발휘합니다.
아래가 예시입니다.

  type paramType = (a: number, b: number) => number;

  let add: paramType = (a, b) => a + b;
  let minus: paramType = (a, b) => a - b;

  console.log(add(1, 2), minus(1, 2)); // 3 -1

타입의 안정성을 확보하면서도 훨씬 짧고 간결해 지지 않았나요? 짧은지 모르시겠다면 add함수, minus함수를 별칭없이 작성해 보시면 감이 확~ 옵니다.

Union type

2개 이상의 타입을 하나의 타입으로 정의합니다.

  const uni = string | number;

 

Intersection type

2개 이상의 타입을 하나로 합치는 타입입니다.

  interface A { args1: string }
  interface B { args2: number }
  let ab: A & B = {args1: "안녕", args2: 1};

참고링크 : https://github.com/microsoft/typescript/wiki/roadmap

반응형