본문으로 바로가기

TS 기본 입문!

category Programming Language/🟦 Typescript 2020. 3. 5. 16:13

 

TS 핸드북, 타입 설명 : (https://typescript-kr.github.io/pages/basic-types.html#%EB%B0%B0%EC%97%B4-array)

한눈에 보는 TS : (https://heropy.blog/2020/01/27/typescript/)

 

JS가 가지고 있는 타입인 Boolean, Number, String, Null, undefined, Symbol, array, object를 기본으로 가지고 있고

 

이에 더해서 any, void, never, enum, tuple을 가지고 있습니다. 주로 any, void, enum을 사용합니다.

 

배열과 튜플의 차이

 

튜플은 배열이되 각 순서와 길이가 정해진 것이라고 보시면 됩니다. [string, number] 꼴의 튜플이라면 길이는 2에 첫 원소가 string, 두번 쨰 원소가 number여야 합니다.

 

함수형 프로그래밍을 위해서 배열과 튜플을 이해하는 것은 중요합니다.

https://darrengwon.tistory.com/758

 

 

배열은 다음과 같이 길이의 제한이 없습니다.

type StringorNumber = number | string;

let list: StringorNumber[] = [1, 2, "doctor"];

 

튜플은 길이의 제한이 있습니다.

아래 튜플은 첫번 째 요소가 string, 두 번째 요소가 number 여야 하고, 길이는 2여야 합니다.

그러나 push와 같은 메서드로 요소를 추가하는 것이 가능합니다.

let tuple: [string, number];

tuple = ["what", 3, 5]; // error

tuple.push(5) // push, assign 등을 통해 tuple에 값을 넣을 수 있음

console.log(tuple) // ["what", 3, 5]

 

 

enum

dart, java, C 등 에서 활용했던 enum과 같습니다.

 

기본적으로는 숫자형 이넘

enum Shoes {
  Nike = 1,
  Adidas,
}

const myShoues = Shoes.Adidas;
console.log(myShoues); // 2

 

숫자형 이넘이 아닌 값을 할당할 수 있다. 문자형 이넘이라고 한다.

enum Shoes {
  Nike = "nike",
  Adidas = "adias",
}

const myShoues = Shoes.Adidas;
console.log(myShoues);

 

특정한 값만 할당하고 싶을 때 이넘을 사용하면 좋다. 필자도 종종 사용하는데 아주 효자다 ㅎ

enum Answer {
  No,
  Yes,
}

function answer(answer: Answer) {
  if (answer === Answer.Yes) {
    console.log("정답");
  } else if (answer === Answer.No) {
    console.log("오답");
  }
}

answer(Answer.No);
answer(Answer.Yes);

 

타입 주석 및 유니언 타입

const sayHi = (name: string, age: number, gender: string): void => {
  console.log(`hello ${name}. you are ${age} years old and ${gender}`);
};

sayHi("nico", 100, "male");

 

함수를 정의할 때 [파라미터: 변수 타입]을 지정하고 함수가 return하는 값의 타입을 적어준다. 이 함수에서는 return하는 값이 없으므로 void를 적어 주었다. 만약 함수가 문자열을 return한다면 다음과 같이 작성되어야 한다.

const sayHi = (name: string, age: number, gender: string): string => {
  return `hello ${name}. you are ${age} years old and ${gender}`;
};

console.log(sayHi("nico", 100, "male"));

 

| 를 통해 유니언 타입(다중 타입)을 선언 할 수도 있습니다. 그런데 string | number라는 타입을 반복적으로 쓸 경우 커스텀 타입을 만드는 것이 좋습니다.

function test(name: string | number): void {
  console.log(`${name}`);
}

test(3);
type StringOrNumber = string | number;

function test(name: StringOrNumber): void {
  console.log(`${name}`);
}

test(3);

 

유니언타입을 쓰다보면 예상대로 타입이 안 먹힐 때가 있는데 이는 typesafe한 동작 방식을 위해 의도된 것입니다.

이런 상황에서 타입 단언 type assersion을 활용하면 좋습니다.

interface IDeveloper {
  name: string;
  skill: string;
}

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


function askTo(a: IDeveloper | IPerson) {
  // a.skill과 a.age가 인텔리센스에 안 잡힌다.
  // 공통되는 a.name만 잡힌다.
  // 이는 a가 IDeveloper일수도, IPerson일수도 있기 때문에 typesafe한 동작 방식을 위해 의도된 것.
  a.name;
}

 

 

타입 추론

 

타입 주석을 달지 않아도 처음 할당한 값에 의해 타입이 추론됩니다. 

const n = 3; // 타입을 명시하지 않았지만 number 타입으로 추론함

n = "nu"; // Error! 

 


optional property

interface IUser {
  name: string,
  age: number,
  isAdult?: boolean // Optional property
}

// `isAdult`를 초기화하지 않아도 에러가 발생하지 않습니다.
let user: IUser = {
  name: 'Neo',
  age: 123
};

 

익명 Interface

 

객체에 곧바로 interface 타입을 지정할 수 있습니다. 익명 인터페이스라고 하니 뭔가 어렵게 들리는 데 쉽게 말해서 그냥 인라인 형식으로 interface 타입을 지정해주는 것 뿐입니다.

let person: {
  name: string;
  age: number;
} = { name: "jack", age: 23 };

console.log(person);

 

주로 함수의 인자에 객체가 들어갈 때 편리하게 사용할 수 있습니다. 물론 가독성을 위해 interface를 분리할수도 있습니다.

function printMe(me: { name: string; age: number }) {
  console.log(me);
}

printMe({ name: "darren", age: 23 });

 

 

type compatibilty (타입 호환)

 

타입 단언, 타입 가드와 같은 새로운 방법은 아니고 TS의 동작 방식입니다.

상식적인 수준에서 이해할 수 있습니다.

// type compatibilty (타입 호환)
interface Developer {
  name: string;
  skills: string;
}

interface Person {
  name: string;
}

let developer: Developer;
let person: Person;

// developer에는 skills가 있지만 person에는 없다.
// 즉, 할당하기 위해서는 할당되는 측(좌측)보다 할당하는 측(우측)이 더 넓은 범위의 속성이어야 함
developer = person; // Error

// developer가 person보다 더 넓어서 이런 방식의 사용은 가능
person = developer; // Good

 

즉, {name}인 값을 {name, skills} 타입에 설정할 수는 있지만

{name, skills} 인 값을 {name} 타입에 설정할 수는 없다는 겁니다.

 

 

함수로 보면 더 쉽습니다.

// type compatibilty (타입 호환)
let add = function (a: number) {
  return a;
};
let sum = function (a: number, b: number) {
  return a + b;
};

add = sum; // 당연히 안됨.
sum = add; // sum이 add보다 더 넓으므로 가능

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체