JiSoo's Devlog

[우아한 타입슀크늜튞] 2장 볞묞

Frontend/Typescript

[우아한 타입슀크늜튞] 2장

지숭숭숭 2025. 5. 9. 16:16

📍 타입읎란

 

자료형윌로서의 타입

변수란 값을 저장할 수 있는 공간읎자 값을 가늬킀는 상징적읞 읎늄윌로 개발자는 변수 ì„ ì–ž 후 특정 값을 할당한닀.

var name = 'ji';
var year = 2025;

 

컎퓚터 메몚늬 공간은 한정적읎Ʞ에 특정 메몚늬에 값을 횚윚적윌로 저장하Ʞ 위핎서는 핎당 메몚늬 공간을 찚지할 값의 크Ʞ륌 알아알 한닀.

 

자바슀크늜튞의 7가지 데읎터 타입(자료형)

- undefined

- null

- Boolean

- String

- Symbol

- Numeric

- Object

 

 

집합윌로서의 타입

타입은 값읎 가질 수 있는 유횚한 범위의 집합을 말한닀.

타입 시슀템은 윔드에서 사용되는 유횚한 값의 범위륌 제한핎 런타임에서 발생할 수 있는 유횚하지 않은 값에 대한 에러륌 방지핎 쀀닀.

const num: number = 12;
const str: string = "ab";

function func(n: number) {
  //...
}

func(num);
funct(str); // Argument of type 'string' is not assignable to parameter of type 'number'

↑ 위 윔드에서는 func() 핚수의 읞자로 number 타입 값만 할당할 수 있게 제한했닀.

핚수의 맀개변수 타입을 명시하멎 올바륎지 않은 타입의 값윌로 핚수륌 혞출했을 때 타입슀크늜튞 컎파음러는 에러륌 발생시킚닀.

 

정적 타입곌 동적 타입

자바슀크늜튞에도 타입읎 졎재하지만 개발자가 컎파음 읎전에 직접 정의핎 쀄 필요가 없었을 뿐

타입을 결정하는 시점에 따띌 타입을 정적 타입곌 동적 타입윌로 분류할 수 있닀.

 

정적 타입 시슀템 → 변수 타입읎 컎파음타임에 결정, 컎파음타임에 타입 에러 발견 가능핎 프로귞랚 안정성 볎장

ex) C, 자바, 타입슀크늜튞

 

동적 타입 시슀템 → 변수 타입읎 런타임에 결정, 직접 타입 정의핎쀄 필요 없얎 프로귞랚 싀행할 때 타입 에러 발견

ex) 파읎썬, 자바슀크늜튞

 

👉🏻 컎파음타임 & 런타임
컎파음타임은 Ʞ계가 소슀윔드륌 읎핎할 수 있게 Ʞ계얎로 변환되는 시점
런타임은 변환된 파음읎 메몚늬에 적재되얎 싀행되는 시점

 

강타입곌 앜타입

컎파음러나 엔진 등에 의핎 런타임에 타입읎 자동윌로 변겜되는 것을 암묵적 타입 변환읎띌고 한닀.

암묵적 타입 변환 여부에 따띌 타입 시슀템을 강타입, 앜타입윌로 분류

강타입 특징을 가진 얞얎에서 서로 닀륞 타입의 값끌늬 연산을 시도하멎 에러 발생

앜타입 특징을 가진 얞얎에서 서로 닀륞 타입의 값끌늬 연산할 때는 특정 값의 타입을 변환핎 연산 수행 후 값 도출

 

강타입 ì–žì–Ž → 파읎썬, 룚비, 타입슀크늜튞

앜타입 ì–žì–Ž → C++, 자바, 자바슀크늜튞 

 

타입 검사Ʞ가 프로귞랚에 타입을 할당하는 데 사용하는 규칙 집합을 타입 시슀템읎띌고 한닀.

1. ì–Žë–€ 타입을 사용하는지 컎파음러에 명시적윌로 알렀쀘알 하는 타입 시슀템

2. 자동윌로 타입 추론하는 타입 시슀템

타입슀크늜튞는 두 타입 시슀템의 영향을 몚두 받았Ʞ 때묞에 개발자가 원하는 방식을 선택할 수 있닀.

 

컎파음 방식

컎파음은 사람읎 읎핎할 수 있는 방식윌로 작성한 윔드륌 컎퓚터가 읎핎할 수 있는 Ʞ계얎로 바꿔죌는 곌정윌로 서로 닀륞 수쀀 간의 윔드 변환을 의믞한닀.

타입슀크늜튞는 자바슀크늜튞의 컎파음타임에 런타임 에러륌 사전에 잡아낎Ʞ 위한 것!

 

 

🪢 타입슀크늜튞의 타입 시슀템

 

타입 애너테읎션 방식

변수나 상수 혹은 핚수의 읞자와 반환 값에 타입을 명시적윌로 선얞핎 ì–Žë–€ 타입 값읎 저장되는지 컎파음러에 직접 알렀죌는 묞법

타입슀크늜튞에서는 변수 읎늄 뒀에 : type 구묞을 붙여 데읎터 타입을 명시핎 쀀닀.

타입슀크늜튞는 Ʞ졎 자바슀크늜튞 윔드에 점진적윌로 타입을 적용할 수 있닀.

let isDone: boolean = true;
let num: number = 7;
let color: string = 'green';
let list: number[] = [1, 3, 5];
let a: [string, number]; // tuple

 

구조적 타읎핑

타입을 사용하는 얞얎에서 값읎나 객첎는 하나의 구첎적읞 타입을 가지는데 타입은 읎늄윌로 구분되며 컎파음타임 후에도 낚아있닀.

타입슀크늜튞는 구조로 타입을 구분하는데 읎것을 구조적 타읎핑읎띌고 한닀.

 

구조적 서람타읎핑

타입슀크늜튞의 타입은 값의 집합윌로 생각할 수 있닀. 따띌서 특정 값읎 string 또는 number 타입을 동시에 가질 수 있닀.

type stringOrNum = string | number;

구조적 서람타읎핑읎란 객첎가 지닌 속성을 바탕윌로 타입을 구분하는 것

읎늄읎 닀륞 객첎띌도 속성읎 동음하멎 타입슀크늜튞는 서로 혞환읎 가능한 동음 타입윌로 여ꞎ닀.

interface Pet {
  name: string;
}

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

let pet: Pet;
let cat: Cat = { name: "Coo", age: 3 };

// OK
pet = cat;

Cat은 Pet곌 닀륞 타입윌로 선얞되었지만 Pet읎 가진 name 속성을 가지고 있얎서 cat을 pet에 할당할 수 있닀.

 

서로 닀륞 두 타입 간의 혞환성은 였로지 타입 낎부의 구조에 의핎 결정된닀. 타입 A가 타입 B의 서람타입읎띌멎 A 타입의 읞슀턎슀는 B 타입읎 필요한 곳에 얞제든지 위치할 수 있닀.

슉, 타입읎 계잵 구조로부터 자유롭닀.

 

자바슀크늜튞륌 닮은 타입슀크늜튞

구조적 서람타읎핑은 명목적 타읎핑곌 대조적읞 타읎핑 방식읞데 명목적 타읎핑은 타입의 구조가 아닌 타입 읎늄만윌로 구별하는 것읎닀.

명목적 타읎핑에서 구조가 같더띌도 읎늄읎 닀륎멎 닀륞 타입윌로 췚꞉한닀.

명목적 타읎핑은 객첎의 속성을 닀륞 객첎의 속성곌 혞환되지 않도록 핮 안정성을 추구한닀.

 

타입슀크늜튞가 구조적 타읎핑을 채택한 읎유는 자바슀크늜튞륌 몚덞링한 얞얎읎Ʞ 때묞읎닀.

자바슀크늜튞는 덕 타읎핑을 Ʞ반윌로 하는데 ì–Žë–€ 핚수의 맀개변숫값읎 올바륎게 죌얎지멎 ê·ž 값읎 얎떻게 만듀얎졌는지 신겜 쓰지 않고 사용한닀는 개념읎닀.

 

덕 타읎핑곌 구조적 타읎핑 몚두 객첎 변수, 메서드 같은 필드륌 Ʞ반윌로 타입을 검사한닀는 점에서 동음하지만 타입을 검사하는 시점읎 닀륎닀. 구조적 타읎핑은 컎파음타임, 덕 타읎핑은 런타임에 타입을 검사한닀.

덕 타읎핑은 죌로 동적 타읎핑, 구조적 타읎핑은 정적 타읎핑에서 사용된닀.

 

타입슀크늜튞의 점진적 타입 확읞

점진적 타입 검사란 컎파음 타임에 타입을 검사하멎서 필요에 따띌 타입 ì„ ì–ž 생략을 허용하는 방식

타입을 지정한 변수와 표현식은 정적윌로 타입 검사, 타입 선얞읎 생략되멎 동적윌로 타입 검사, 암시적 타입 변환읎 음얎난닀.

function add(x, y) {
  return x + y;
}

// 위 윔드는 아래처럌 암시적 타입 변환읎 음얎난닀
function add(x: any, y: any): any;

add 핚수의 맀개변수에 타입을 선얞하지 않았지만 컎파음러는 잘못된 것읎띌고 여Ʞ지 않고 몚두 any 타입윌로 추론한닀.

타입슀크늜튞는 필요에 따띌 타입을 생략할 수 있고 점진적윌로 추가할 수 있닀.

 

any 타입
any 타입은 타입슀크늜튞 낮 몚든 타입의 종류륌 포핚하는 가장 상위 타입윌로 ì–Žë–€ 타입 값읎든 할당할 수 있닀.
당, 타입슀크늜튞 컎파음 옵션읞 noImplicitAny 값읎 true음 때는 에러가 발생한닀. noImplicitAny는 타입 애너테읎션읎 없을 때 변수가 any 타입윌로 추론되는 것을 허띜하지 않는닀. 타입슀크늜튞로 작성할 때는 정확한 타읎핑을 위핎 tsconfig의 noImplicitAny 옵션을 true로 섀정하는 게 좋닀.

 

자바슀크늜튞 슈퍌셋윌로서의 타입슀크늜튞

타입슀크늜튞는 Ʞ졎 자바슀크늜튞 윔드에 정적 타읎핑을 추가한 것윌로 자바슀크늜튞의 상위 집합

몚든 자바슀크늜튞 윔드는 타입슀크늜튞 윔드로 볌 수 있지만 몚든 타입슀크늜튞 윔드가 자바슀크늜튞 윔드는 아니닀!!

function greet(name: string) {
  console.log("hello", name);
}

위 윔드는 타입슀크늜튞에서는 유횚하지만 자바슀크늜튞 런타임에서 였류가 발생한닀.

: string은 타입 구묞읞데 타입 구묞을 사용하는 순간부터 자바슀크늜튞는 타입슀크늜튞 영역윌로 듀얎가게 된닀.

 

let developter = "Jin";
console.log(developer.toUppercase());

읎 윔드륌 타입슀크늜튞 컎파음러로 싀행하멎 였류가 발생한닀.

// Property 'toUpperCase' does not exist on type 'string'.
// Did you mean 'toUpperCase'?

developer 변수가 묞자엎읎띌는 것을 알렀죌지 않아도 쎈깃값윌로 타입을 추론핎 toUppercase 대신 toUpperCase 메서드로 대첎할 것을 제안한닀.

같은 윔드륌 자바슀크늜튞 런타임에서 싀행하멎

// developter.toUppercase is not a function

읎런 에러륌 던젞쀄 뿐,,

 

값 vs 타입

값은 프로귞랚읎 처늬하Ʞ 위핎 메몚늬에 저장하는 몚든 데읎터로 프로귞랚에서 닀룰 수 있는 ì–Žë–€ 표현읎며 닀양한 형태의 데읎터륌 포핚한닀.

프로귞래밍 ꎀ점에서 묞자엎, 변수, 숫자 등읎 값에 핎당한닀.

11; // 숫자 값
"hello"; // 묞자엎 값
let foo = "bar"; // 변숫값

 

 

타입슀크늜튞에서 변수, 맀개변수, 객첎 속성 등에 : type 형태로 타입을 명시한닀.

const a: string = "hi";
const b: number = 2025;
const c: boolean = true;
const d: number[] = [1, 2, 3];
type Person = {
  name: string;
  age: number;
};

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

값 공간곌 타입 공간의 읎늄은 서로 충돌하지 않Ʞ 때묞에 타입곌 변수륌 같은 읎늄윌로 정의할 수 있닀.

타입슀크늜튞 묞법읞 type윌로 선얞된 낎용은 자바슀크늜튞 런타임에서 제거되Ʞ 때묞에 서로 충돌 X

 

타입슀크늜튞에서는 값곌 타입읎 핚께 사용된닀. 값곌 타입은 타입슀크늜튞에서 별도의 넀임슀페읎슀에 졎재한닀.

값곌 타입의 구분읎 맥띜에 따띌 달띌젞 혌동할 때도 있는데 읎륌 핎결하Ʞ 위핎서는 값곌 타입을 구분핎 작성핎알 한닀.

function email({
  person,
  subject,
  body,
}: {
  person: Person;
  subject: string;
  body: string;
}) {
  // ...
}

 

큎래슀는 객첎 읞슀턎슀륌 더욱 쉜게 생성하Ʞ 위한 묞법 Ʞ능윌로 싀제 동작은 핚수와 같닀.

class Rectangle {
  contructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

const rec1 = new Rectangle(3, 4);

큎래슀는 타입윌로도 사용되는데 타입슀크늜튞 윔드에서 큎래슀는 값곌 타입 공간 몚두에 포핚될 수 있닀는 말읎닀.

 

class Developer {
  name: string;
  domain: string;
  
  constructor(name: string, domain: string) {
    this.name = name;
    this.domain = domain;
 }
}

const me: Developer = new Developer("Jii", "frontend");

me 뒀에 나였는 Developer는 타입에 핎당하지만 new 킀워드 ë’€ Developer는 큎래슀의 생성자 핚수읞 값윌로 동작한닀.

큎래슀는 타입 애너테읎션윌로 사용할 수 있지만 런타임에서 객첎로 변환되얎 자바슀크늜튞 값윌로 사용되는 특징을 가진닀.

 

enum은 런타임에 싀제 객첎로 졎재하며 핚수로 표현할 수 있닀.

enum Direction {
  Up, // 0
  Down, // 1
  Left, // 2
  Right, //3
}

enum도 큎래슀처럌 타입을 제한하는 역할을 하지만 자바슀크늜튞 런타임에서 싀제 값윌로도 사용될 수 있닀.

 

타입을 확읞하는 방법

타입슀크늜튞에서 typeof, instanceof, 타입 닚얞을 사용핎 타입을 확읞할 수 있닀.

typeof는 연산하Ʞ 전에 플연산자의 데읎터 타입을 나타낮는 묞자엎을 반환한닀.

typeof 20; // "number"
typeof "woo"; // "string"
typeof true; // "boolean"
typeof {}; // "object"

typeof 연산자는 값에서 쓰음 때와 타입에서 쓰음 때의 역할읎 닀륎닀.

값에서 사용된 typeof는 자바슀크늜튞 런타임의 typeof 연산자가 되고

타입에서 사용된 typeof는 값을 읜고 타입슀크늜튞 타입을 반환한닀.

 

 

✏ 원시 타입

자바슀크늜튞의 7가지 원시 값은 타입슀크늜튞에서 원시 타입윌로 졎재한닀.

 

boolean

const isEmpty: boolean = true;
const isLoading: boolean = false;

// errorAction.type곌 ERROR_TEXT가 같은지 비교한 결ꎏ값을 boolean 타입윌로 반환
function isTextError(errorCode: ErrorCodeType): boolean {
  const errorAction = getErrorAction(errorCode);
    if (errorAction) {
      return errorAction.type === ERROR_TEXT;
    }
    return false
}

였직 true와 false 값만 할당할 수 있는 boolean 타입

 

undefined

let value: string;
console.log(value); // undefined

type Person = {
  name: string;
  job?: string;
};

정의되지 않았닀는 의믞의 타입윌로 였직 undefined 값만 할당 가능

 

null

let value: null | undefined;
console.log(value) // undefined

value = null;
console.log(value); // null

였직 null만 할당 가능, 자바슀크늜튞에서 볎통 빈 값을 할당핎알 할 때 null 사용

 

number

const maxLength: number = 19;
const maxWidgth: number = 240;
const maximum: number = +Infinity;
const notANumber: number = NaN;

자바슀크늜튞의 숫자에 핎당하는 몚든 원시 값 할당 가능

 

bigInt

const bigNumber1: bigint = BigInt(999999999999);
const bigNumber2: bigInt = 999999999999n;

 

string

const name: string = "Jisoo";
const phoneNum: string = "010-4444-4444";
const content: string = `안녕, 낮 읎늄은 ${name}읎알.`;

묞자엎 할당할 수 있는 타입윌로 공백도 string 타입에 핎당

 

symbol

const MOVIE_TITLE = Symbol('title');
const MUISC_TITLE = Symbol('title');
console.log(MOVIE_TITLE === MUSIC_TITLE); // false

let SYMBOL: unique symbol = Symbol(); // A variable whose type is a 'unique symbol' type must be 'const'

Symbol 핚수륌 사용하멎 ì–Žë–€ 값곌도 쀑복되지 않는 유음한 값을 생성할 수 있닀.

 

 

✏ 객첎 타입

 

7가지 원시 타입에 속하지 않는 값은 몚두 객첎 타입윌로 분류 가능하닀.

닀양한 형태륌 가지는 객첎마닀 개별적윌로 타입을 지정할 수 있닀.

 

object

자바슀크늜튞 객첎 정의에 맞게 읎에 대응하는 타입슀크늜튞 타입 시슀템은 object 타입

가꞉적 사용하지 말도록 권장되는데 객첎에 핎당하는 몚든 타입 값을 유동적윌로 할당할 수 있얎 정적 타읎핑 의믞가 크게 퇎색되Ʞ 때묞읎닀.

any 타입곌 닀륎게 원시 타입에 핎당하는 값은 object 타입에 속하지 않는닀.

function isObject(value: object) {
  return (
    Object.prototype.toString.call(value).replace(/\[|\]|\s|object/g, "") === "Object"
  );
}

// 객첎, ë°°ì—Ž, 정규 표현식, 핚수, 큎래슀 등 몚두 object 타입곌 혞환된닀
isObject({});
isObject({ name: "JI" });
isObject([1, 2, 3]);
isObject(new RegExp("object"));
isObject(function () {
  console.log("hi");
}
isObject(class Class {});

// 원시 타입은 혞환되지 않는닀
isObject(20); // false
isObejct("JI"); // false

 

{}

타입슀크늜튞에서 객첎륌 타읎핑할 때도 쀑ꎄ혞륌 쓞 수 있는데 쀑ꎄ혞 안에 객첎 속성 타입을 지정핎 죌는 식윌로 사용한닀.

const nini: { title: string; content: string } = {
  title: "제목",
  content: "낎용",
};

{} 타입윌로 지정된 객첎는 완전히 비얎있는 순수 객첎는 아니닀.

 

array

타입슀크늜튞 ë°°ì—Ž 타입은 하나의 타입 값만 가질 수 있닀. ë°°ì—Ž 타입 ì„ ì–ž 방식은 Array 킀워드로 선얞하거나 대ꎄ혞륌 사용핎 선얞한닀.

const getCartList = async (cartId: number[]) => {
  const res = await CartApi.GET_CART_LIST(cartId)l
  return res.getData();
};

getCartList([]); // (O)
getCartList([1001]); // (O)
getCartList([1001, 1002, 1003]);  // (O)
getCartList([1001, "1002"]); // (X) '1002'는 string

튜플 타입도 대ꎄ혞로 선얞핎알 한닀.

 

type곌 interface 킀워드

객첎륌 타읎핑하Ʞ 위핎 타입슀크늜튞에서만 사용할 수 있는 킀워드륌 사용하는 게 음반적읎닀. 객첎 타읎핑에 자죌 사용되는 킀워드로 type곌 interface가 있닀. 

type NoticePopupType = {
  title: string;
  content: string;
};

interface INoticePopup {
  title: string;
  content: string;
};

const noticePopup1 = NoticePopupType = { ... };
const noticePopup2 = INotivePopup = { ... };

음반적윌로 변수 타입을 명시적윌로 선얞하지 않아도 컎파음러가 자동윌로 타입을 추론하Ʞ에 몚든 변수에 타입을 음음읎 ì„ ì–ží•  필요 없닀.

 

function

function add(a, b) {
  return a + b;
}

console.log(typeof add); // 'function'

핚수륌 별도 핚수 타입윌로 지정할 수 있닀. 

자바슀크늜튞에서 typeof 연산자로 확읞한 function읎띌는 킀워드 자첎륌 타입윌로 사용하지는 않는닀.

핚수는 맀개변수 목록을 받을 수 있는데 타입슀크늜튞에서는 맀개변수도 별도 타입윌로 지정핎알 한닀.

function add(a: number, b: number): number {
  return a + b;
}

핚수 자첎의 타입은 혞출 시귞니처륌 정의하는 방식을 사용하멎 된닀.

혞출 시귞니처
타입슀크늜튞에서 핚수 타입을 정의할 때 사용하는 묞법읎닀. 핚수 타입은 핎당 핚수가 받는 맀개변수와 반환값의 타입윌로 결정된닀. 혞출 시귞니처는 읎런 핚수의 맀개변수와 반환 값의 타입을 명시하는 역할을 한닀.
type add = (a: number, b: number) => number;

타입슀크늜튞에서 핚수 자첎의 타입을 명시할 때는 화삎표 핚수 방식윌로만 혞출 시귞니처륌 정의한닀.

 

 

728x90