TypeScript 첫 번째

2025. 7. 22. 16:32Next.js + TypeScript

1. 기본 타입

1-1 원시 타입

 

  • boolean (불리언): true 또는 false 값
    let isDone: boolean = false;
    
  • number (숫자): 정수, 부동 소수점 숫자 등 모든 숫자
    let decimal: number = 6;
    let hex: number = 0xf00d;
    let binary: number = 0b1010;
    
  • string (문자열): 텍스트 데이터. 백틱(`)을 사용한 템플릿 리터럴도 가능
    let fullName: string = "John Doe";
    let sentence: string = `Hello, my name is ${fullName}.`;
    
  • null과 undefined: 자바스크립트와 동일한 의미를 가짐. 기본적으로 다른 모든 타입의 하위 타입으로 간주
    let u: undefined = undefined;
    let n: null = null;
    

     

    symbol (심볼): ECMAScript 2015에 추가된 고유하고 변경 불가능한 값
    const sym: symbol = Symbol('key');
    

     

  • bigint (큰 정수): ES2020에 추가된, 매우 큰 정수를 다룰 때 사용
    let bigNumber: bigint = 100n;

 

 

1-2 특별 타입

 

  • any (모든 타입): 어떤 타입의 값이라도 할당할 수 있음을 나타냄. 타입스크립트의 장점을 해치므로 가능한 한 사용을 피해야 함.
    let notSure: any = 4;
    notSure = "maybe a string instead";
    notSure = false; // boolean
    
  • unknown (알 수 없는 타입): any와 비슷하게 어떤 타입의 값이든 가질 수 있지만, any보다 타입 안정성이 높음. unknown 타입의 값을 사용하려면 먼저 타입을 좁히는 작업(예: typeof 또는 instanceof를 사용한 타입 검사)이 필요.
    let value: unknown = 10;
    value = "hello";
    
    // let someString: string = value; // 오류: 'unknown' 타입은 'string' 타입에 할당될 수 없음
    
    if (typeof value === 'string') {
        let someString: string = value; // 이제 안전하게 string으로 사용 가능
    }
  • void (반환 값이 없음): 주로 함수가 아무런 값을 반환하지 않을 때 사용
    function warnUser(): void {
        console.log("This is my warning message");
    }
    
  • never (절대 도달할 수 없는 타입): 함수가 값을 반환할 수 없거나(항상 예외를 던지거나 무한 루프에 빠지는 경우) 절대 도달할 수 없는 코드 경로를 나타낼 때 사용.
    function error(message: string): never {
        throw new Error(message);
    }
    
    function infiniteLoop(): never {
        while (true) {}
    }

 

 

 

 

2. 타입 명시하기

2-1. 변수 타입 명시

변수 이름 뒤에 콜론(:)을 붙이고 타입을 작성

let age: number = 30;
let name: string = "Alice";
let isActive: boolean = true;

 

 

2-2 함수 타입 명시

함수의 매개변수와 반환 값에 타입을 명시

// 매개변수 타입 명시
function add(x: number, y: number): number { // 반환 값도 number 타입이라고 명시
    return x + y;
}

let result = add(5, 3); // result는 자동으로 number 타입으로 추론됨
// add("5", 3); // 오류: 'string' 타입의 인수는 'number' 타입의 매개변수에 할당될 수 없음

 

 

2-3 배열의 타입은 두 가지 방식으로 정의

  1. 요소 타입 뒤에 [ ] 붙이기:
    let list: number[] = [1, 2, 3];
  2. 제네릭 배열 타입 Array<엘리먼트타입> 사용:
    let list: Array<number> = [1, 2, 3];

 

2-4 튜플

튜플은 요소의 개수와 각 요소의 타입이 미리 정해진 배열. 정의된 순서와 타입에 맞춰 값을 할당해야 함.

// string과 number 타입을 가지는 두 개의 요소 튜플
let x: [string, number];

x = ["hello", 10]; // 성공
// x = [10, "hello"]; // 오류: 순서와 타입이 맞지 않음
// x = ["hello", 10, true]; // 오류: 요소 개수가 맞지 않음

 

 

2-5 열거형 (enum)

열거형은 특정 값들의 집합에 이름을 부여하는 것. 기본적으로 숫자 열거형으로 동작하며, 문자열 열거형도 가능.

1. 숫자 열거형 (Numeric Enums)

각 멤버는 자동으로 0부터 시작하는 숫자로 할당. 값을 수동으로 지정할 수도 있음.

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

let dir: Direction = Direction.Up; // dir은 0
console.log(dir); // 0
console.log(Direction.Left); // 2

// 값을 수동으로 지정
enum Status {
    Pending = 1,
    Success, // 2
    Failed   // 3
}
console.log(Status.Success); // 2

2. 문자열 열거형 (String Enums)

모든 멤버에게 문자열 값을 할당해야함.

enum UserRole {
    Admin = "ADMIN",
    Editor = "EDITOR",
    Viewer = "VIEWER"
}

let role: UserRole = UserRole.Admin;
console.log(role); // "ADMIN"

 

 

 

2-6 객체

객체의 속성들에 타입을 정의할 수 있음.

// 익명 객체 타입 정의
let user: { name: string; age: number; };

user = {
    name: "Bob",
    age: 25
};

// user = { name: "Bob" }; // 오류: age 속성이 없음

// 선택적 속성 (Optional Properties): ? 를 붙이면 해당 속성이 없어도 됨.
let anotherUser: { name: string; age?: number; };
anotherUser = { name: "Charlie" }; // age 속성 없어도 됨

// 읽기 전용 속성 (Readonly Properties): readonly 를 붙이면 초기 할당 후 변경 불가
let config: { readonly id: string; url: string; };
config = { id: "123", url: "http://example.com" };
// config.id = "456"; // 오류: 읽기 전용 속성이므로 변경 불가

 

 

2-7 타입 별칭

복잡한 타입을 재사용하거나 코드의 가독성을 높이고 싶을 때 type 키워드를 사용하여 타입 별칭을 정의할 수 있음.

type User = {
    id: number;
    name: string;
    email?: string; // 선택적 속성
};

type Admin = User & { //type의 확장
	isAdmin: boolean;
}

let admin: User = {
    id: 1,
    name: "Admin User",
    email: "admin@example.com",
    isAdmin: true
};

let guest: User = {
    id: 2,
    name: "Guest User"
};

type Point = [number, number]; // 튜플 타입에 대한 별칭
let coordinate: Point = [10, 20];

type ID = string | number; // 유니온 타입에 대한 별칭 (아래 설명)
let userId: ID = "abc-123";
let productId: ID = 456;

 

 

2-8 인터페이스

인터페이스는 객체의 모양(shape)을 정의하는  방법. 객체가 가져야 할 속성과 메서드를 명시. type 별칭과 비슷하지만, 주로 객체의 구조를 정의하는 데 사용되며 확장(extends) 및 구현(implements)이 가능.

interface Person {
    name: string;
    age: number;
    greet(): string; // 메서드 정의
}

class Employee implements Person { // 클래스가 인터페이스를 '구현'
    name: string;
    age: number;
    employeeId: string; // Employee에만 있는 속성

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

    greet() {
        return `Hello, my name is ${this.name} and I am an employee.`;
    }
}

let john: Person = {
    name: "John",
    age: 30,
    greet: function() {
        return `Hello, my name is ${this.name}.`;
    }
};

interface Animal {
    name: string;
}

interface Dog extends Animal { // 인터페이스 확장
    breed: string;
}

let myDog: Dog = {
    name: "Buddy",
    breed: "Golden Retriever"
};



interface User{
	name: string
}

interface User{
	age: number
}

const user: User = { //같은 이름의 인터페이스는 병합됨. type은 불가능
	name: "kim",
    age: 20
}

 

 

2-9

유니온 타입은 두 개 이상의 타입 중 하나가 될 수 있음을 의미. 파이프 기호(|)를 사용하여 정의.

function printId(id: number | string) {
    console.log(`Your ID is: ${id}`);
    // 여기서 id는 number 또는 string 타입일 수 있으므로,
    // 해당 타입에 공통적으로 사용 가능한 속성/메서드만 직접 접근 가능.

    // 예를 들어
    // id.toUpperCase(); // 오류: number 타입에는 toUpperCase 메서드가 없음
    if (typeof id === "string") {
        console.log(id.toUpperCase()); // 타입 좁히기 후 사용 가능
    }
}

printId(101); // Your ID is: 101
printId("202"); // Your ID is: 202
// printId(true); // 오류: 'boolean' 타입의 인수는 'number | string' 타입에 할당될 수 없음

 

 

2-10 인터섹션 타입

인터섹션 타입은 두 개 이상의 타입을 모두 만족하는 타입을 생성하는 것. 앰퍼샌드 기호(&)를 사용하여 정의

interface Draggable {
    drag(): void;
}

interface Resizable {
    resize(): void;
}

type UIElement = Draggable & Resizable; // Draggable과 Resizable의 모든 속성을 가짐

let button: UIElement = {
    drag() { console.log("드래그!"); },
    resize() { console.log("리사이즈!"); }
};

button.drag();
button.resize();

 

 

2-11 리터럴 타입

리터럴 타입은 특정 고정된 값 자체를 타입으로 사용하는 것. 특정 문자열, 숫자, 불리언 값만 허용하도록 제한할 때 유용.

TypeScript
 
type Direction = "north" | "south" | "east" | "west"; // 유니온 리터럴 타입

let move: Direction = "north";
// move = "up"; // 오류: '"up"' 타입은 'Direction' 타입에 할당될 수 없음

type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";

function fetchData(url: string, method: HTTPMethod) {
    // ...
}

fetchData("/api/users", "GET");
// fetchData("/api/users", "PATCH"); // 오류

 

'Next.js + TypeScript' 카테고리의 다른 글

TypeScript 두 번째  (1) 2025.07.22
Next.js 두 번째  (0) 2025.07.22
Next.js 시작  (0) 2025.07.18