TypeScript - Handbook(Everyday Types)

2021. 5. 28. 18:28프론트엔드/Typescript

728x90

https://www.typescriptlang.org/docs/handbook/2/everyday-types.html

 

Documentation - Everyday Types

The language primitives.

www.typescriptlang.org

이번에는 TypeScirpt에서 사용할 수 있는 Type들에 대해서 알아볼 것이다.


원시 Type들 (Primitives)

자바스크립트에서 사용되는 세가지 원시 타입들.
이 세가지는 이름 그대로 사용할 수 있다.

const name:string = "inho";
const age:number = 27;
const died:boolean = false;

배열, any

배열은 두가지 표현 방식이 있다.

const ages:number[] = [1, 2, 3];
const ages2:Array<number> = [1, 2, 3];

다음과 같이 'Type[]'으로 쓰거나, 'Array<Type>'으로 쓴다.

any는 그냥 any로 쓰면 된다.


Type 명시와 자동 적용

Type 명시는 기본적으로 변수 선언시에 변수명 뒤에 쓴다.
하지만 초기값에 따라 자동으로 적용되기도 한다.

let myName:string = "Alice";
let yourName = "Inho";

yourName은 Type을 명시하지 않았지만, 초기값이 string이기 때문에 자동으로 string이 된다.


함수에서의 Type 명시

함수에서는 인자, 반환값에 대한 Type명시가 필요하다.

function greet(name: string): string {
  console.log("Hello World!");
  
  return name + ", Hi";
}

Object 타입

Object는 각 값이 어떤 타입인지 명시하여야 한다.

function printCoord(pt: { x: number; y: number }) {
  console.log("The coordinate's value is " + pt.x + ", " + pt.y);
}
printCoord({ x: 3, y: 7 });

Type이름대신, Object의 형식으로 명시한다.

포함될수도, 없을수도 있는 내용은 ?를 붙인다.

function printCoord(pt: { x: number; y?: number }) {
  console.log("The coordinate's x value is " + pt.x);
  
  if (y !== undefined) {
    console.log("The coordinate's y value is " + pt.y);
  }
}
printCoord({ x: 3, y: 7 });

값이 없을 수도 있으므로, Optional한 Property에 대해서는 undefined체크를 해준다.


Union 타입

Union 타입은 여러가지 타입, 값 중에 하나일 때 사용한다.
여러가지 타입을 받을 때, 여러가지 값 중에 하나를 받을 때,
타입과 특정 값이 복합적인 경우에도 사용할 수 있다.

let people:1 | 10 = 1;
let name:string | string[] = "a";
let combined:string | 5 | 10 = 5;

다음과 같이 케이스를 나누어 처리할수도 있다.

function welcomePeople(x: string[] | string) {
  if (Array.isArray(x)) {
    // Here: 'x' is 'string[]'
    console.log("Hello, " + x.join(" and "));
  } else {
    // Here: 'x' is 'string'
    console.log("Welcome lone traveler " + x);
  }
}

Type 선언 (Type Aliases)

특정 값과 타입을 가진 object를 type으로 선언하여 활용할 수 있다.

type ID = number | string;

type Point = {
  x: ID;
  y: ID;
};

// Exactly the same as the earlier example
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}

printCoord({ x: 100, y: 100 });

이런 식으로 'type 이름 = 명시'의 형식으로 사용할 수 있다.


인터페이스 (Interfaces)

인터페이스는 Type alias와는 비슷하지만 다른 점을 지니고 있다.
1. 인터페이스는 Type과는 달리 확장이 용이하다.

// Animal에 honey를 포함한 Bear를 확장하여 정의하였다.
interface Animal {
  name: string
}

interface Bear extends Animal {
  honey: boolean
}

2. type과는 다르게 같은 이름의 interface를 재정의할 수 있다.

// 똑간은 Window지만 둘 다 사용할 수 있음
interface Window {
  title: string
}

interface Window {
  ts: number
}

// 심지어 둘 다 포함할 수도 있음
const window:Window = {
  title: "inho",
  ts: 5,
};

3. type은 원시 타입(primitives)을 재정의할 수 있지만, interface는 아니다.

type SanitizedString = string
type EvenNumber = number

타입 어썰션 (Type Assertion)

가끔 프로그래밍을 하다보면 실제로 사용하는 타입과 반환되는 타입이 다를 수 있다.
다음의 예를 보자.

class Animal {
  name:string;
}

class Bear extends Animal {
  honey:number;
}

const bear:Animal = new Bear();
// bear은 Animal로 선언 되어있기 때문에 불가능하다
console.log(bear.honey);

그런 경우에 as를 이용해서 원하는 타입으로 assert해주면 된다.

const bear:Animal = new Bear()
const realBear:Bear = bear as Bear;
console.log(realBear.honey)

타입으로 값을 특정시키기 (Literal Types)

let a: 1 | 5 | 10 = 10;
a = 5;
// 정해진 값을 벗어나기 때문에 불가능
a = 7;

그리고 인터페이스에도 적용이 되는 사례도 있다.

function whoAreYou(name: "Inho" | "Ahrem") {
  console.log(`Hi, ${name}`);
}

const person = { name: "Inho", age: 27 };
// 불가능
whoAreYou(person.name);

person객체의 name은 "Inho"이기 때문에 가능해보인다. 하지만 실제로는 가능하지 않다.
왜냐하면 person의 properties는 { name: string; age: number } 로 정의되어있기 때문이다.
그러므로 "Inho" | "Ahrem" 타입과는 매칭이 되지 않는다.

이런 경우의 대처 방법은 다음과 같다.

// 1. 선언을 "Inho"타입으로 바꾼다.
const person = { name: "Inho" as "Inho", age: 27 };
whoAreYou(person.name);

// 2. 호출시에 "Inho"타입으로 어썰션한다.
const person = { name: "Inho", age: 27 };
whoAreYou(person.name as "Inho");

// 3. const로 어썰션한다.
const person = { name: "Inho", age: 27 } as const;
whoAreYou(person.name);

null과 undefined

이전 포스팅에서도 있듯, strictNullCheck 플래그를 통하여 엄격하게 체크할 수 있다.

null을 처리하는 방법

1. null인지 직접 확인하여 처리한다.

function doSomething(x: string | null) {
  if (x === null) {
    // do nothing
  } else {
    console.log("Hello, " + x.toUpperCase());
  }
}

2. Not-null 어썰션 연산자를 사용하기

function liveDangerously(x?: number | null) {
  // No error
  console.log(x!.toFixed());
}

간단하게 설명하면, x가 null이라면 해당 프로시저가 스킵된다.