TypeScript 치트시트
마지막 업데이트
기본 타입
원시 타입과 변수에 타입을 표기하는 방법.
| 동작 | 문법 |
|---|---|
| 문자열 | let name: string = "Ada"; |
| 숫자 | let age: number = 25; |
| 불리언 | let ok: boolean = true; |
| T 배열 | let xs: number[] = [1, 2, 3]; |
| 제네릭 배열 | let xs: Array<string> = []; |
| 튜플 | let pair: [string, number] = ["a", 1]; |
| Any (타입 검사 해제) | let x: any = 1; |
| Unknown (안전한 any) | let x: unknown = JSON.parse(s); |
| Void (반환 없음) | function log(): void { … } |
| Never (반환하지 않음) | function fail(): never { throw … } |
| Null / undefined | let n: null = null; |
타입 추론과 표기
언제 TS에 맡기고 언제 직접 표기할지.
| 동작 | 문법 |
|---|---|
| 값으로부터 추론 | let count = 0; // number |
| 명시적 표기 | let count: number = 0; |
| 함수 매개변수 | function add(a: number, b: number) { … } |
| 반환 타입 | function add(a: number, b: number): number { … } |
| 화살표 함수 | const sq = (x: number): number => x * x; |
| 타입 단언 | const el = input as HTMLInputElement; |
| const 단언 (리터럴) | const dirs = ["up", "down"] as const; |
| non-null 단언 | el!.focus(); |
인터페이스
객체의 모양을 기술합니다.
| 동작 | 문법 |
|---|---|
| 선언 | interface User { id: number; name: string; } |
| 선택 속성 | interface User { age?: number; } |
| readonly 속성 | interface User { readonly id: number; } |
| 메서드 시그니처 | interface Logger { log(msg: string): void; } |
| 다른 인터페이스 확장 | interface Admin extends User { role: string; } |
| 인덱스 시그니처 | interface Map { [key: string]: number; } |
| 클래스에서 구현 | class Db implements Logger { … } |
타입 별칭과 유니온
타입에 이름을 붙이고 |와 &로 결합합니다.
| 동작 | 문법 |
|---|---|
| 타입 별칭 | type ID = string | number; |
| 객체 별칭 | type User = { id: number; name: string }; |
| 유니온 타입 | type Status = "idle" | "loading" | "done"; |
| 인터섹션 타입 | type Admin = User & { role: string }; |
| 리터럴 타입 | type Yes = "yes"; |
| Nullable | type Maybe<T> = T | null | undefined; |
| 함수 별칭 | type Handler = (e: Event) => void; |
함수
타입이 붙은 매개변수, 반환, 오버로드.
| 동작 | 문법 |
|---|---|
| 선택 매개변수 | function greet(name?: string) { … } |
| 기본값 매개변수 | function greet(name = "friend") { … } |
| rest 매개변수 | function sum(...ns: number[]): number { … } |
| 함수 타입 | let fn: (a: number) => number; |
| 호출 가능한 인터페이스 | interface Fn { (x: number): number; } |
| 오버로드 시그니처 | function f(x: string): string; function f(x: number): number; function f(x: any) { return x; } |
| void 반환은 무시됨 | const cb: () => void = () => 42; // ok |
클래스
접근 제어자와 매개변수 속성을 가진 클래스.
| 동작 | 문법 |
|---|---|
| 클래스 선언 | class User { name: string; } |
| 생성자 | constructor(name: string) { this.name = name; } |
| 매개변수 속성 | constructor(public name: string) {} |
| public / private / protected | private id: number; |
| readonly 필드 | readonly id: number; |
| 정적 멤버 | static count = 0; |
| getter / setter | get name() { return this._name; } |
| 상속 | class Admin extends User { … } |
| 추상 클래스 | abstract class Shape { abstract area(): number; } |
제네릭
다른 타입으로 매개변수화하는 재사용 가능한 타입.
| 동작 | 문법 |
|---|---|
| 제네릭 함수 | function id<T>(x: T): T { return x; } |
| 명시적 타입으로 호출 | id<string>("hi"); |
| 제네릭 인터페이스 | interface Box<T> { value: T; } |
| 제네릭 별칭 | type Pair<A, B> = [A, B]; |
| 제네릭 클래스 | class Stack<T> { items: T[] = []; } |
| extends로 제약 | function len<T extends { length: number }>(x: T) { return x.length; } |
| 기본 타입 매개변수 | interface Box<T = string> { value: T; } |
| keyof 연산자 | type K = keyof User; // "id" | "name" |
| 인덱스 접근 타입 | type Name = User["name"]; |
타입 좁히기 (Narrowing)
런타임에 유니온을 한 타입으로 좁혀나가기.
| 동작 | 문법 |
|---|---|
| typeof 검사 | if (typeof x === "string") { … } |
| instanceof 검사 | if (e instanceof Error) { … } |
| in 연산자 | if ("name" in obj) { … } |
| 동등성으로 좁히기 | if (status === "done") { … } |
| truthy 검사 | if (value) { … } |
| 커스텀 타입 가드 | function isUser(x: any): x is User { return "id" in x; } |
| 식별 유니온 | type Shape = { kind: "sq"; size: number } | { kind: "ci"; r: number }; |
| never로 완전성 확인 | const _: never = shape; |
Enum
이름이 있는 상수 집합.
| 동작 | 문법 |
|---|---|
| 숫자 enum | enum Direction { Up, Down, Left, Right } |
| 문자열 enum | enum Status { Idle = "IDLE", Done = "DONE" } |
| 값 사용 | let d: Direction = Direction.Up; |
| const enum (인라인화) | const enum Color { Red, Green, Blue } |
| 리터럴 유니온 (현대적 방식) | type Status = "idle" | "done"; |
유틸리티 타입
기존 타입을 변형하는 내장 헬퍼.
| 동작 | 문법 |
|---|---|
| 모든 속성을 선택적으로 | Partial<User> |
| 모든 속성을 필수로 | Required<User> |
| 모든 속성을 readonly로 | Readonly<User> |
| 키의 부분집합 선택 | Pick<User, "id" | "name"> |
| 하나 이상의 키 제외 | Omit<User, "password"> |
| 지정한 키의 객체 | Record<string, number> |
| 유니온에서 제외 | Exclude<"a" | "b" | "c", "a"> |
| 유니온에서 추출 | Extract<"a" | "b", "a" | "c"> |
| null / undefined 제거 | NonNullable<string | null> |
| 함수 반환 타입 | ReturnType<typeof fn> |
| 매개변수 튜플 | Parameters<typeof fn> |
| resolved Promise 타입 | Awaited<Promise<string>> |
모듈
파일 간 import와 export.
| 동작 | 문법 |
|---|---|
| 이름 있는 export | export function add(a: number, b: number) { … } |
| 기본 export | export default class User { … } |
| 재 export | export { User } from "./user"; |
| 이름 있는 import | import { add } from "./math"; |
| 기본 import | import User from "./user"; |
| 타입만 import | import type { User } from "./user"; |
| 전체 import | import * as math from "./math"; |
| triple-slash 참조 | /// <reference types="node" /> |
tsconfig 핵심
알아두면 좋은 컴파일러 플래그.
| 옵션 | 효과 |
|---|---|
"strict": true | 모든 엄격 모드 검사 활성화 (권장). |
"target": "ES2022" | tsc가 출력하는 JavaScript 버전. |
"module": "ESNext" | 출력 결과의 모듈 시스템. |
"moduleResolution": "bundler" | 최신 번들러 방식으로 모듈 해석. |
"jsx": "react-jsx" | React 17+ 용 JSX 활성화. |
"esModuleInterop": true | CommonJS 모듈로부터의 default import가 깔끔해짐. |
"skipLibCheck": true | node_modules 타입 검사 생략 (빌드 가속). |
"noEmit": true | 타입 검사만 수행 — 출력은 번들러가 담당. |
가장 자주 쓰는 TypeScript 문법을 한 페이지에 모았습니다. 이 TypeScript 치트시트는 일상적인 TS 작업을 위한 빠른 참조서입니다 — 기본 타입, 인터페이스, 타입 별칭, 제네릭, 유니온, 좁히기, 내장 유틸리티 타입까지.
여기에 있는 모든 내용은 tsc로 컴파일되고 최신 JavaScript가 동작하는 곳이면 어디서든 실행되는 표준 TypeScript입니다. 필요한 부분을 복사하거나, TypeScript 플레이그라운드에서 바로 실행해 보세요 — 설치 필요 없습니다.
TypeScript 치트시트 자주 묻는 질문
이 TypeScript 치트시트는 무료인가요?
네. 이 TypeScript 치트시트는 가입 없이 완전히 무료입니다. 북마크에 저장해 두고 타입, 인터페이스, 유틸리티 타입이 필요할 때마다 다시 찾아보세요.
interface와 type alias의 차이는 무엇인가요?
둘 다 객체의 모양을 기술할 수 있고, 일상적인 대부분의 상황에서는 서로 바꿔 쓸 수 있습니다. interface는 여러 파일에 걸쳐 다시 열고 확장할 수 있어 (declaration merging) 라이브러리 타입에 유용합니다. type alias는 유니온, 인터섹션, 튜플, mapped type 같은,
interface로는 표현할 수 없는 형태에도 이름을 붙일 수 있습니다. 흔히 쓰는 기준은: 공개 객체 모양에는 interface, 유니온·튜플·계산된 타입에는 type을 쓰는 것입니다.any와 unknown의 차이는 무엇인가요?
any는 타입 검사를 완전히 해제합니다 — 컴파일러가 어떤 동작이든 허용합니다. unknown은 타입 안전합니다. 사용하기 전에 (typeof, instanceof, 타입 가드로) 좁혀야 합니다. JSON.parse나 fetch처럼 외부에서 들어오는 값에는 unknown을 선호하세요 — 사용 전에 검증을 강제할 수 있습니다.TypeScript 전에 JavaScript를 배워야 하나요?
네 — TypeScript는 JavaScript 위에 타입 시스템을 얹은 것이라, JS 지식이 그대로 활용됩니다. 배열, 객체, async/await 같은 기초를 다지고 있다면 JavaScript 치트시트가 좋은 출발점이며, Coddy의 무료 JavaScript 코스는 같은 내용을 인터랙티브하게 다룹니다.
TypeScript를 온라인에서 연습할 수 있나요?
네. TypeScript 플레이그라운드를 열면 이 치트시트의 모든 코드 조각을 브라우저에서 실행할 수 있습니다 — 설치 필요 없습니다. 체계적으로 배우고 싶다면 JavaScript 랜딩에서 시작한 다음, 이 페이지의 타입을 그 위에 얹어 적용해 보세요.