TypeScript - tutorial

승진·2020년 5월 2일
1
post-thumbnail

Setting

$ mkdir ts-practice # ts-practice 라는 디렉터리 생성
$ cd ts-practice # 해당 디렉터리로 이동
$ yarn init -y # 또는 npm init -y

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}
  • target: 컴파일된 코드가 어떤 환경에서 실행될 지 정의합니다. 예를들어서 화살표 함수를 사용하고 target 을 es5 로 한다면 일반 function 키워드를 사용하는 함수로 변환을 해줍니다. 하지만 이를 es6 로 설정한다면 화살표 함수를 그대로 유지해줍니다.
  • module: 컴파일된 코드가 어던 모듈 시스템을 사용할지 정의합니다. 예를 들어서 이 값을 common 으로 하면 export default Sample 을 하게 됐을 때 컴파일 된 코드에서는 exports.default = helloWorld 로 변환해주지만 이 값을 es2015 로 하면 export default Sample 을 그대로 유지하게 됩니다.ㅕ
  • strict: 모든 타입 체킹 옵션을 활성화한다는 것을 의미합니다.
  • esModuleInterop: commonjs 모듈 형태로 이루어진 파일을 es2015 모듈 형태로 불러올 수 있게 해줍니다.
$ yarn global add typescript
$ tsc --init // tsconfig.json 자동생성

error

zsh: command not found: tsc

해결

brew install typescript

Type

src/practice.ts

const message: string = 'hello world';
console.log(message);

타입스크립트는 이렇게 *.ts 확장자를 사용하고, message 값이 선언된 코드에 : string 부분이 해당 상수 값이 문자열 이라는 것을 명시해준다.

해당 값을 string이 아닌 타입을 설정한다면 에디터 상에서 오류가 나타나게 된다.

let count = 0;
count += 1;
count = '문자열 넣으면 에러';

const message: string = 'hello';

const done: boolean = true;

const numbers: number[] = [1,2,3] //숫자 배열
const messages: string[] = ['hello', 'world'] // 문자열 배열

message.push(1); // 숫자 넣으면 에러

let mightBeUndefined: string | undefined = undefined;
// string 또는 undefined
let nullableNumber: number | null = null;
// number 또는 null

let color: 'red' | 'orange' | 'yellow' = 'red'; // 셋 중 하나
color = 'yellow';
color = 'green'; // error!

TypeScript 를 사용하면 이렇게 특정 변수 또는 상수의 타입을 지정 할 수 있고 우리가 사전에 지정한 타입이 아닌 값이 설정 될 때 바로 에러를 발생시킨다.

이렇게 에러가 나타났을땐 컴파일이 되지 않는다. 한번 tsc 명령어를 입력해서 컴파일을 하려고 하면 다음과 같이 실패한다.

$ tsc

src/practice.ts:3:1 - error TS2322: Type '"문자열 넣으면 에러"' is not assignable to type 'number'.

3 count = "문자열 넣으면 에러";
  ~~~~~

src/practice.ts:12:9 - error TS2339: Property 'push' does not exist on type 'string'.

12 message.push(1); // 숫자 넣으면 에러
           ~~~~

src/practice.ts:21:1 - error TS2322: Type '"green"' is not assignable to type '"red" | "orange" | "yellow"'.

21 color = "green"; // error!
   ~~~~~


Found 3 errors.

Function Type

function sum(x: number, y: number): number {
  return x + y;
}

sum()

타입스크립트를 사용하면 다음과 같이 코드를 작성하는 과정에서 함수의 파라미터로 어떤 타입을 넣어야 하는지 바로 알 수 있다.

function sumArray(numbers: number[]): number {
  return numbers.reduce((acc, current) => acc + current, 0);
}

const total = sumArray([1, 2, 3, 4, 5]);

배열의 내장함수를 사용할 때도 타입 유추가 매우 잘 이루어진다.

만약 아무것도 return하지 않는 함수의 경우에는 void 타입을 지정해준다.

function returnNothing(): void {
  console.log("I am just saying hello world");
}

Object Tpye

interface
interface는 클래스 또는 객체를 위한 타입을 지정 할 때 사용되는 문법
클래스와 관련된 타입의 경우엔 interface 를 사용하는게 좋고, 일반 객체의 타입의 경우엔 그냥 type을 사용해도 무방하다.

interface Person {
  name: string;
  age?: number; // ? = 설정을 해도 되고 안해도 되는 값.
}

interface Developer extends Person {
  skills: string[];
}

const person: Person = {
  name: "김사람",
  age: 20,
};

const expert: Developer = {
  name: "김개발",
  skills: ["javascript", "react"],
};

const people: Person[] = [person, expert];

Generics

제너릭(Generics)은 타입스크립트에서 함수, 클래스, interface, type alias 를 사용하게 될 때 여러 종류의 타입에 대하여 호환을 맞춰야 하는 상황에서 사용하는 문법이다.

함수에서 Generics 사용하기
예를 들어서 우리가 객체 A 와 객체 B 를 합쳐주는 merge 라는 함수를 만든다고 가정해봅시다. 그런 상황에서는 A 와 B 가 어떤 타입이 올 지 모르기 떄문에 이런 상황에서는 any 라는 타입을 쓸 수도 있습니다.

function merge(a: any, b: any): any {
  return {
    ...a,
    ...b
  };
}

const merged = merge({ foo: 1 }, { bar: 1 });

이렇게 하면 타입 유추가 모두 깨진거나 다름이 없다. 결과가 any 라는 것은 즉 merged 안에 무엇이 있는지 알 수 없다는 것이다.

이런 상황에 Generics 를 사용하면 된다.

function merge<A, B>(a: A, b: B): A & B {
  return {
    ...a,
    ...b,
  };
}

const merged = merge({ foo: 1 }, { bar: 1 });
profile
Front-end 개발 공부일지

0개의 댓글