본문 바로가기

🌼 TIL

🌞 1/17 내배캠 React 56일차 [typescript]

[ Typescript ]

오늘도 typescript에 대해서 이어서 공부를 진행했다.

Enum / Union / Interface /제네릭 / 타입 추론 등을 배웠다.

 

Enum 타입

자바스크립트에는 없고 타입스크립트에만 있는 타입

enum은 특정 값들의 집합을 의미하는 자료형

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

const up: Direction = Direction.Up;
// Direction = Direction.UP | Direction.Down | Direction.Left | Direction.Right
const leftOrRight: Direction.Left | Direction.Right = Direction.Left;

Union 타입 : (A || B )

자바스크립트의 or 연산자 || 와 같은 의미이다.

const printOut = (input: string | number) => {
	console.log(input);
}

printOut('문자열');
printOut(20);
printOut(true);

" | "을 활용하여 string 이나 number를 type에 넣을 수 있다.

 

Type Alias

매번 타입을 새로 작성하는 건 번거롭고 재사용이 불가능 하기 때문에 type 키워드를 사용한다

// type.ts

type Hero = {
	name: string;
	power: number;
	height: number;
};


import type { Hero } from './type';

const hero1: Hero = {
  name: '슈퍼맨',
  power: 1000,
  height: 190,
};

const printHero = (hero: Hero) => {
  console.log(hero.name, hero.power);
};

console.log(printHero(hero1));

프로젝트의 규모가 커지면 따로 type Alias 파일을 만들고 type들을 몰아놓고 import해와서 사용한다. 예시의 Hero처럼

 

Interface & Intersection Type

ts에서는 좀 더 다양한 것들을 정의한다

interface Person {
  name: string;
  age: number;
}

const person1: Person = { name: 'js', age: 20 };
const person2: Person = { name: 'ljs', age: 'twenty' }; // Error

age는 number type이기 때문에 'twenty'는 error가 뜬다.

 

interface 선택속성

interface Person {
// //   name: string;
// //   age?: number;
// // }

// // const person1: Person = { name: "js"};

age에 ?를 넣어 age가 있어도 되고 없어도 된다 -> name: 'js' 만 입력해도 error가 뜨지 않는다.

 

Interface Extends 인터페이스 확장

interface는 type과는 달리 확장이 가능하다

extends를 이용하여 또다른 interface를 확장 할 수 있다

interface Person {
  name: string;
  age: number;
}

interface Korean extends Person {
  birth: 'KOR';
}

interface Korean {
  name: string;
  age: number;
  birth: 'KOR';
}

interface Developer {
  job: 'developer';
}

interface KorAndDev extends Korean, Developer {}

interface KorAndDev {
  name: string;
  age: number;
  birth: 'KOR';
  job: 'developer';
}

type vs interface

타입 별칭과 인터페이스의 가장 큰 차이점은 타입의 확장 가능 / 불가능 여부입니다.

인터페이스는 확장이 가능한데 반해 타입 별칭은 확장이 불가능합니다.

따라서, 가능한한 type 보다는 interface로 선언해서 사용하는 것을 추천합니다.

 

제네릭

타입을 마치 함수의 파라미터처럼 사용하는 것

function getText(text: any): any {
  return text;
}

getText('hi'); // 'hi'
getText(10); // 10
getText(true); // true

이 코드를 <T>를 활용하여 이렇게 변경할 수 있다

function getText<T>(text: T): T {
  return text;
}

getText<string>('hi');
getText<number>(10);
getText<boolean>(true);

<string>...은 생략할 수 있다.

 

타입 추론

type을 넣지 않아도 자동으로 type을 추론하는 것

let a = 123; // a는 number라고 type 추론 중
let b = "abc"; // b는 string이라고 type 추론 중

a = "abc"; // error
b = 123; // error
const c1 = 123; 
const c2 = "abc";

let과 const에 차이가 존재한다. 

let은 재할당이 가능해서 조금 유연하게 추론하고, const는 재할당이 불가능하므로 엄격하게 type을 추론한다

그래서 위의 

const c1 = 123은 number가 아니라 123으로 추론된다. number는 맞는데 수많은 number중 123이라는 type이다 (엄격)

 

함수또한 타입추론이 가능하다

const func1 = (a = "a", b = 1) => {
  // a = string, b = number 추론
  return `${a} ${b};`;
};
func1(3, 6); //a 는 string이기 때문에 error

const v1: number = func1("a", 1); //func1 함수는 string을 반환하기 때문에 v1이 number가 될 수 없다 error

const func2 = (value: number) => { // 반환값은 number 또는 string 이다. if문을 사용했기 때문
  if (value < 10) {
    return value;
  } else {
    return `${value} is big`;
  }
};