TypeScript Study day-2 _ basic type

hwibaski·2021년 12월 17일
0

TypeScript & JavaScript

목록 보기
13/15

드림코딩엘리님의 TypeScript 강의를 토대로 정리했습니다.

4. Type Alias(사용자 정의 타입)

  • 기본 타입외에 사용자가 타입의 이름을 지정할 수 있다.
// Text란 타입은 없다. 하지만 별명을 붙혀서 타입을 지정할 수 있다.
type Text = string;
const name: string = 'hwimin';
const alphabet: Text = 'a'
type Num = number;
  • 객체의 프로퍼티도 타입을 지정할 수 있다.
type Student = {
  name: string;
  age: number;
};

const student: Student = {
  name: 'hwimin',
  age: 10,
};

const student: Student = {
  animal: 'dog' // name 프로퍼티가 없기 때문에 error 발생
}
  • 인덱스 시그니쳐를 이용해서 유연하게 사용 가능하다.
type Signature = {
  a: number;
  [key: string]: number; // key는 문자열이고 value는 숫자형 타입으로 설정 가능, 여러 개의 프로퍼티도 추가 가능
//  [key: number]: boolean; --> 이런 식으로 두 개의 index signature를 설정할 순 없다.
}

const test: Signature = {
  a: 1,
  b: 2, 
  c: 3,
  1: true --> 에러 -> key의 타입이 숫자형이기 때문에 에러가 난다.
}

index signature 외에도 Record라는 기능도 있습니다. 링크를 따라가시면 인덱스 시그니처에 대해서 조금 더 상세하게 다루는 글이 나옵니다. https://dmitripavlutin.com/typescript-index-signatures/

5. String Literal Type

  • 타입을 지정할 뿐만 아니라 특정 값만 할당할 수 있도록 지정할 수도 있다.
type Name = 'name';
let myName: name;
myName = 'name';
myName = 'hwimin'; // 'name'이 아니기 때문에 error 발생

type JSON = 'json';
const json: JSON = 'json';

type Bool = true;
const isCat: Bool = true;
const isCat: Bool = false; // true 가 아니기 때문에 error 발생

6. Union Types

  • 프로그래밍 언어에서 or 과 비슷한 역할을 한다.
  • String literal type과 조합하면 활용도가 높다.
type Direction = 'left' | 'right' | 'up' | 'down';

function move(direction: Direction) {
  console.log(direction);
}

move('right');
move('left');
move('abc') // error : 'left', 'right', 'up', 'down' 중 하나가 인수로 대입되어야 한다.

type TileSize = 8 | 16 | 32;
const title: TileSize = 16;

6-1. 예시

로그인의 상태를 리턴해주는 함수를 만든다고 가정해봅시다.

type SuccessState = {
  response: {
    body: string;
  }
}

type FailState = {
  reason: string;
}

type LoginState = SuccessState | FailState;

// LoginState에 SuccessState | FailState가 들어갈 수도 있지만,
// 따로 type을 지정을 해서 관리할 수도 있다.

function login(id: string, password: string): LoginState {
// Promise<LoginState> 실제 프로젝트에서는 프로미스겠죠?
  return {
    response: {
      body: 'logged in!',
    },
  };
}

function printLoginState(state: LoginState) {
// state.response.body -> 이런 식으로 접근이 불가하다.
// Union Type이기 때문에 state 객체 내에 response가 있는지 없는지 알 수 없다.
  if ('response' in state) {
    console.log(`🚀 ${state.response.body}`);
  } else {
  // console.log(${state.response}) ->  문법을 이해하는건가? state.response에 접근이 불가하다.
    console.log(`😇 ${state.reason}`);
  }
}

7. Discriminated Unions

  • 6-1 예시의 printLoginState 의 if문 안에서 in 연산자를 사용해서 state 객체를 확인하고 있다.
  • state.result 처럼 dot notation을 이용해서 접근하고 싶다면 SuccessStateFailState 타입에 공통으로 result 라는 프로퍼티를 추가해주면 dot notation으로 접근할 수 있다.
type SuccessState = {
  result: 'success';
  response: {
    body: string;
  };
};
	
type FailState = {
  result: 'fail';
  reason: string;
};

type LoginState = SuccessState | FailState;

function printLoginState(state: LoginState) {
  state.result; // success or fail
  if (state.result === 'success') {
    console.log(`🚀 ${state.response.body}`);
  } else {
    console.log(`😇 ${state.reason}`);
  }
 }
}

8. Enum type

  • 관련된 상수들을 한 곳에 모아서 관리할 수 있는 타입

8-1. JavaScript 에서의 상수

  • 대문자를 사용해서 상수라는 것을 나타낸다.
  • Object.freeze({}) 를 사용해서 외부에서 변경할 수 없는 객체를 지정할 수 있다.
const MAX_NUM = 6;
const MAX_STUDENTS_PER_CLASS = 10;
const MONDAY = 0;
const TUESDAY = 1;
const WEDNESDAY = 2;
const DAYS_ENUM = Object.freeze({ MONDAY: 0, TUESDAY: 1, WEDNESDAY: 2 });
const dayOfToday = DAYS_ENUM.MONDAY;

8-2. TypeScript의 enum

  • enum 타입 지정 후 값을 지정하지 않으면 자동적으로 0부터 차례대로 숫자들 할당함
enum Days {
  Monday,    // 0
  Tuesday,   // 1
  Wednesday, // 2
  Thursday,  // 3
  Friday,    // 4
  Saturday,  // 5
  Sunday,    // 6
}

console.log(Days.Monday); // 0
let day = Days.Friday // 4
  • 내가 원하는 값으로 지정을 하고 싶다면?
  • enum에 설정된 아이템에 값을 할당할 수도 있다. 값이 할당되지 않은 아이템은 이전 아이템의 값에 +1된 값이 설정된다.
  • 문자열은 그 다음의 값을 유추하기 어렵기 때문에 수동으로 값을 입력해줘야 한다.
enum Days {
  Monday = 1,    
  Tuesday = 100,
  Wednesday, // 101
  Thursday,  // 102
  Friday,    // 103
  Saturday = 'saturday',
  Sunday = 'sunday', // 입력하지 않을 시 컴파일 불가
}

8-3. enum 타입의 사용은 괜찮은가?

  • 타입스크립트의 enum 은 위험성을 가지고 있다.
enum Days {
  Monday,    // 0
  Tuesday,   // 1
  Wednesday, // 2
  Thursday,  // 3
  Friday,    // 4
  Saturday,  // 5
  Sunday,    // 6
}

let day: Days = Days.saturday
// day 변수는 Days(enum)타입을 가질 수 있는데 이 때,
// enum이 가지고 있는 타입을 임의로 지정할 수 있다.
// enum내에 Tuesday가 1이 될 수 있으므로 1이 그냥 할당이 가능해진다.
day = 1
// 문제는 enum타입이 가지고 있지 않는 숫자도 할당이 가능하다.
day = 10 // 에러가 나지 않는다. 컴파일도 문제 없이 생성된다.
  • union type 을 이용해서 enum 의 역할을 대신할 수 있다. 이 방법이 더 안전하다.
type Day = 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 'Sunday'
let dayOfWeek: Day = 'Monday'

9. type inference(타입 추론)

  • 최초에 변수를 초기화(할당)할 때 문자열을 지정한다면, TypeScript가 그 변수의 타입을 문자열로 추론(추측해서 지정)한다. 그 이후 다른 문자열로는 할당이 가능하지만, 그 외의 타입으로 할당이 불가능하다.
  • 타입 추론 간편하고 좋은것인가?
  • 개인의 생각마다 다르겠지만, 웬만하면 타입을 지정해주는 것이 정확하고 안전하다.
  • 함수의 void 타입이라면 그나마 생략 가능.
let text = 'hello';
text = 'hi';
text = 1; // error
text = {}; // error

// 함수의 매개변수에는 자동으로 any로 추론한다. 그러므로 type을 지정해주는 것이 좋다.
function print(message) {
  console.log(message)
}

print('hello')
print(1)
  • default parameter를 지정해줄 경우 지정된 parameter 의 타입으로 지속적으로 추론한다.
function printStr(message = 'hi') {
  console.log(message)
}

printStr('hello');
printStr(1); // error
  • 들어오게될 매개변수의 타입이 둘 다 number 타입이므로 return 값의 타입도 number 일 것이라고 추론한다.
function add(x: number, y: number) {
  return x + y;
}

// add 함수는 return 값을 number 타입으로 추론했따.
// 그 함수의 리턴 값을 변수에 담는다면, 그 변수 또한 number 타입이라고 추론한다.
const result = add(1, 2);

0개의 댓글