TypeScript 기본문법 정리

TypeScript = 자바스크립트에 타입을 붙인 것

 

쓰는 이유?

- 컴파일 전에 오류를 잡아줌

- 자동완성 + 리팩토링이 미친 듯이 좋아짐

- 협업 / 대규모 프로젝트 필수

- TS는 "문법"이 아니라 " 안전장치"라고 생각하면됨

 

1. 타입 붙이기

Javascript

let count = 0;
count = "hello"

 

- 자바스크립트는 런타임 실행 전까지 에러인지 모름

 

Typescript

let count: number = 0;
count = "hello";

 

- 타입스크립트는 컴파일시 에러가 발생하여 바로 확인이 가능함

 

자주 쓰는 기본 타입

let userName: string = "kim"
let age: number = 30;
let isLogin: boolean = true;

 

Typescript 타입 추론

let price = 100;

 

- pice 뒤에 : number를 선언하지 않아도 값을 보고 자동으로 타입을 추론함

 

2. 배열 & 객체

let numbers: number[] = [1, 2, 3];
let users: string[] = ["kim", "lee"];

 

3. interface / type

interface

interface User {
  id: number;
  email: string;
  isAdmin: boolean;
}

const user: User = {
  id: 1,
  email: "test@test.com",
  isAdmin: false,
};

 

3-1 interface를 써야하는 상황

DTO / API 응답 구조

interface UserDto {
  id: number;
  email: string;
  name: string;
}

interface ApiResponse<T> {
  success: boolean;
  data: T;
  message?: string;
}

Vue props 정의

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

const props = defineProps<{
  user: User;
  isAdmin: boolean;
}>();

implements

interface LoginService {
  login(email: string, password: string): Promise<void>;
}

class AuthService implements LoginService {
  async login(email: string, password: string) {
    // ...
  }
}

 

확장 (extends)

interface BaseEntity {
  id: number;
  createdAt: string;
}

interface User extends BaseEntity {
  email: string;
}

 

 

type

type User = {
  id: number;
  email: string;
  isAdmin: boolean;
};

 

객체 구조 정의 -> interface

union, 함수 타입 -> type

 

3-2. type를 써야하는 상황

Union 타입

type Status = "idle" | "loading" | "error";
let status: Status = "loading";

 

함수 타입 정의

type LoginFn = (email: string, password: string) => Promise<void>;
const login: LoginFn = async (email, password) => {
  // ...
};

 

조합 타입 (intersection)

type WithToken = {
  accessToken: string;
};

type User = {
  id: number;
  email: string;
};

type AuthedUser = User & WithToken;

 

제네릭 + 조건 타입

type ApiResult<T> = 
  T extends string ? { value: string } : { value: number };

4. 함수 타입

4-1. 기본 함수

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

 

4-2. 화살표 함수

const add = (a: number, b: number): number => {
  return a + b;
};

 

4-3. return 없는 함수

function log(msg: string): void {
  console.log(msg);
}

 

5. Optional / Nullable

5-1. Optional

interface User {
  id: number;
  name?: string; // 있어도 되고 없어도 됨
}

const u1: User = { id: 1 };
const u2: User = { id: 2, name: "kim" };

 

- name뒤에 ?를 붙이면 값이 있을수도 있고 없을수도 있다라는 의미임

 

5-2. null / undefined

let token: string | null = null;

token = "abc";
token = null; // OK

 

- token 값의 타입이 string이거나 null일수 있다 라는 의미

 

6. Union 타입

let status: "idle" | "loading" | "success" | "error";
status = "loading";
status = "done";   // 컴파일 에러

 

- 상태값에 done을 선언하지 않아서 컴파일 에러

 

7. any

let data: any = 123;
data.toUpperCase(); // 런타임 에러

 

- any는 어떤타입이든 들어올수 있다라고 설정하는거여서, 사용하면 typescript 쓰는 의미가 없음

- 123을 대문자로 바꾸려니 런타임 에러 발생

 

8. Unknown

let data: unknown;

if (typeof data === "string") {
  data.toUpperCase();
}

- unknown은 타입을 아직 모른다는걸 typescript에게 솔직하게 말하는 타입

 

9. any vs unknown

let data: any;

data = 123;
data = "hello";

data.toUpperCase();

 

- any로 선언을하면 toUpperCase 컴파일은 통과하지만, 런타임에서 에러가 발생함

 

let data: unknown;

data = 123;
data = "hello";

data.toUpperCase();

 

- unknown으로 선언하면 toUpperCase 컴파일에서 에러가 발생함, 즉 unknown은 확인하고 쓰라는걸 강제함