티스토리 뷰

타입스크립트 핸드북을 통해 타입스크립트 이해하기 시작합니다!

이 글에서는 낮은 수준의 타입스크립트 이해와 시작하기 위한 설명을 작성해 두었습니다.

또한 타입스크립트의 시작을 위한 타입스크립트의 구조적인 부분에 대한 내용입니다.

더 자세한 사항은 이후 글을 통해서 다룰 예정입니다.

 

레퍼런스 : https://www.typescriptlang.org/ko/docs/handbook/typescript-in-5-minutes.html

 

Documentation - TypeScript for JavaScript Programmers

Learn how TypeScript extends JavaScript

www.typescriptlang.org

 

 

 

타입 추론 (Types by Inference)

타입스크립트는 자바스크립트의 변수 생성 동시에 타입을 생성해줍니다.

 

let helloWorld = "Hello World";
// let helloWorld:string

 

타입 정의하기 (Defining Types)

변수 생성 동시에 타입이 생성이 되지만 동적 언어인 자바스크립트의 특징을 살려 타입스크립트는 인터페이스로써 명시적으로 타입을 선언해 줄 수 있습니다.

 

const user = {
  name: "Jone",
  id: 0,
};

// 선언과 동시에 객체의 타입이 지정됩니다.
/*
  const user: {
      name: string;
      id: number;
}
*/

 

interface를 통한 명시적 타입 선언

interface User {
  name: string;
  id: number;
}

const user: User = {
  name: "Jone",
  id: 0,
};

 

선언된 interface에 맞지 않는 객체를 생성시 경고

interface User {
  name: string;
  id: number;
}

const user2: User = {
  userName: "",
  id: 0,
};
/*
경고!
Type '{ userName: string; id: number; }' is not assignable to type 'User'.
  Object literal may only specify known properties, and 'userName' does not exist in type 'User'.
*/

 

자바스크립트의 클래스에 interface로 타입 선언하기

interface User {
  name: string;
  id: number;
}

class UserAccount {
  name: string;
  id: number;

  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
}

const user: User = new UserAccount("jone", 1);

 

interface를 통해 함수의 매개변수와 리턴 값을 명시하는 경우

// return에 interface 활용
function getUser(): User {
  // ....
  return { name: "cha", id: 12 };
}

// 매개변수에 interface 활용
function deleteUser(user: User) {
  // ....
}

 

자바스크립트에서 사용할 수 있는 원시 타입 종류

- boolean, bigint, null, number, string, symbol, object, undefined

const boolean_type: boolean = true;
const bigint_type: bigint = BigInt(10000000000);
const null_type: null = null;
const number_type: number = 10;
const string_type: string = "string";
const symbol_type: symbol = Symbol("symbol");
const object_type: object = {};
const undefined_type: undefined = undefined;

 

 

interface 과 type

타입스크립트에서 타입을 선언하는 별칭을 두가지 방법을 제시해주고 있습니다. 바로 interface와 type입니다.

타입스크립트 핸드북에서는 다음과 같이 interface와 type을 사용함에 있어 추천해주고 있습니다.

interface and Types - interface를 우선적으로 사용하고!! 특정 기능이 필요할 때 type을 사용해야 합니다.

interface와 type중 interface를 왜 우선적으로 사용해야 더 좋은지 설명한 글은 이곳을 참고해주시길 바랍니다.

 

 

타입스크립트에서 추가 되어 확장된 목록

- any, unknown, never

const any_type: any = { any: "any", wow: null };
const unkown_type: unknown = { unknown: "haha...", idontknow: "hm...." };
let never_type: never;

 

 

타입 구성 (Composing Types)

객체들을 더 동적이며 복잡하게 만들때 타입스크립트는 이 동작을 수행할 수 있도록 해주는 도구가 있습니다.

바로 유니언(Union)제네릭(Generic) 입니다.

 

유니언 (Union)

유니언은 여러 타입일 수도 있다고 선언하는 방식입니다.

// 이와 같이 선언하면 해당 타입이 사용된 변수에서는 true와 false 값을 할당 받을 수 있게됩니다.
type IsOpen = true | false;

let isOpen: IsOpen = true;
isOpen = false;

 

리터럴 집합과 타입의 처리 방법

유니언 타입이 많이 사용되는 곳은 string 또는 number의 리터럴 집합을 설명할 때 많이 사용됩니다.

type Breakpoints = "xs" | "sm" | "md" | "lg" | "xl";
type Spacing = 0 | 4 | 8 | 12 | 16 | 20 | 24;

let myBreakpoints: Breakpoints = "sm";
let mySpacing: Spacing = 12;

// 함수에서 매개변수에서 유니언 타입을 통해 처리를 다양하게 해줄 수 있습니다.
function createBreakpoints(breakpoints: Breakpoints | Breakpoints[]) {
  // ...
  return breakpoints.length;
}

createBreakpoints("xl");
createBreakpoints(["xl", "sm"]);

 

변수가 변경되는 방식을 이해하는 타입스크립트

typeof 또는 자바스크립트의 메서드를 통해서 변수의 타입을 골라낼 수 있습니다.

- string, number, boolean, undefined, function, array

type TypeCheckerParams =
  | string
  | number
  | boolean
  | undefined
  | Function
  | Array<any>;

function typeChecker(n: TypeCheckerParams) {
  if (typeof n === "string") {
    // ...
    return "this is string";
  } else if (typeof n === "number") {
    // ...
    return "this is number";
  } else if (typeof n === "boolean") {
    // ...
    return "this is boolean";
  } else if (typeof n === "undefined") {
    // ...
    return "this is undefined";
  } else if (typeof n === "function") {
    // ...
    return "this is function";
  } else if (Array.isArray(n)) {
    // ...
    return "this is array";
  }
}

 

제네릭 (Generics)

제네릭은 타입에 변수를 제공하는 방법입니다.

쉽게 말해서 배열 안의 값이 어떠한 형식으로 제공되고 있는지를 설명할 수 있습니다.

type StringArray = Array<string>;
type NumberArray = Array<number>;
type UserArray = Array<{ name: string; id: number }>;

const stringArray = ["string1", "string2"];
const numberArray = [1, 2, 3, 4];
const userArray = [
  { name: "Jone", id: 0 },
  { name: "Tom", id: 1 },
];

다음과 같이 고유 타입을 선언해 줄 수 있습니다.

interface User {
  name: string;
  id: number;
}

interface UserSystem<UType> {
  add: (user: UType) => void;
  get: () => UType;
}

// declare은 해당 선언한 변수가 존재하고 할당한 타입이 어느것인지 알 수 있도록 해줍니다.
declare const userSystem: UserSystem<User>;

userSystem.add({ name: "Jone", id: 0 });
const userSystemObj = userSystem.get();

 

구조적 타입 시스템 (Structural Type System)

타입스크립트는 형태에 집중하며 이를 "덕 타이핑(duck typing)" 또는 "구조적 타이핑" 이라고 부릅니다. 

두 객체가 같은 형태를 가지면 같다고 판단한다는 것을 의미합니다.

 

구조적으로 객체의 타입이 같은 형태이면 타입이 같다고 판단합니다.

interface Point {
  x: number;
  y: number;
}

function debugPoints(p: Point) {
  console.log(`${p.x}, ${p.y}`);
}

const point = { x: 10, y: 20 };
debugPoints(point);

// 다음 구조는 형태가 같지 않아 경고가 표시됩니다.
const notPoint = { width: 10, height: 20 };
debugPoints(notPoint);
// type error

 

구조적으로 객체의 타입이  클래스(또는 객체)에서 모든 속성에서 존재한다면 세부 정보에 관계없이 같다고 판단합니다.

interface Point {
  x: number;
  y: number;
}

function debugPoints(p: Point) {
  console.log(`${p.x}, ${p.y}`);
}

class VirtualPoint {
  x: number;
  y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

// 다음 클래스는 constructor을 통해 구조적으로 x와 y의 객체 형태를 가지고 있어 Point타입이 같다고 판별합니다.
const newPoint = new VirtualPoint(10, 20);
debugPoints(newPoint);
// 10, 20
댓글
최근에 올라온 글