ABOUT ME

작은 디테일에 집착하는 개발자

Today
-
Yesterday
-
Total
-
  • [TypeScript] 타입 스크립트 헷갈리는 기초 문법
    IT Study/컴퓨터 기초 2023. 10. 3. 13:39
    728x90

    위 책으로 공부하고 있습니다 :)

     

    "[위키북스] 타입스크립트, 리액트, Next.js로 배우는 실전 웹 애플리케이션 개발" 책을 통해

    TS, Next.js를 공부하고 있습니다.

     

    1. 옵셔널 인수 (생략 가능, 인수명 뒤 ? 붙이기)

    function sayHello(name: string, greeting?: string): string {
        return `${greeting}, ${name}`;
    }
    
    console.log(sayHello("Three")); // 출력 : undefined, Three
    console.log(sayHello("스리", "안녕")); // 출력 : 안녕, 스리

     

    2. 인수의 기본값 지정 (=)

    function sayHello(name: string, greeting: string = "안녕"): string {
        return `${greeting}, ${name}`;
    }
    
    console.log(sayHello("한슬")); // 출력 : 안녕, 한슬
    console.log(sayHello("여러분", "안녕하세요")); // 출력 : 안녕하세요, 여러분

     

    3. 함수를 인수로 지정

    TypeScript에서도 함수는 일급 객체로 취급됩니다.

    이는 함수를 변수에 할당하거나, 다른 함수에 전달하거나, 함수에서 반환하는 등의

    다양한 활용이 가능하다는 것을 의미합니다.

    function printName(firstName: string, formatter: (name: string) => string) {
        console.log(formatter(firstName));
    }
    
    function formatName(name: string): string {
        return `${name}씨`
    }
    
    printName("김한슬", formatName); // 출력 : 김한슬씨
    
    let sayHello = (name: string): string => `Hello ${name}`;
    console.log(sayHello("김한슬")); // 출력 : Hello 김한슬

     

    4. 타입 Alias

    type Point = {
        x: number;
        y: number;
    }
    
    function printPoint(point: Point) {
        console.log(`좌표 (${point.x}, ${point.y})`)
    }
    
    printPoint({x: 10, y: 20});
    printPoint({x: 30, y: 40});

     

    키 이름과 키의 개수가 미리 정해지지 않은 경우 아래와 같은 형태로 타입 앨리어스를 선언할 수 있습니다.

    *Index signature (인덱스 타입)이라고도 부른다.

    type 타입명 = {
      [ key: 키 값 타입 ]: 객체 값의 타입
    }

    key : 식별자, 다른 이름으로 바꿔도 상관없습니다.
    다만, 의미를 명확히 전달하기 위해서는 일반적으로 key, property, index와 같은 이름이 사용됩니다.
    type Label = {
        [key: string] : string
    }
    
    const labels: Label = {
        topTitle: "페이지 제목",
        subTitle: "페이지 부제목",
        featureSection: "기능 섹션",
    }
    
    console.log(labels)

     

     

    5. 타입 Alias가 있는데 왜 interface를 사용할까?

    타입 Alias는 같은 이름으로 타입을 정의할 수 없으나, interface는 확장(추가)이 가능하다.

     

    6. 클래스

    extends를 통한 클래스 상속

    class Point {
        x: number;
        y: number;
    
        constructor(x: number = 0, y: number = 0) {
            this.x = x;
            this.y = y;
        }
    
        moveX(n: number): void {
            this.x += n;
        }
        
        moveY(n: number): void {
            this.y += n;
        }
    }
    
    const point = new Point();
    console.log(`(${point.x}, ${point.y})`); // 출력 : (0, 0)
    
    point.moveX(10);
    console.log(`(${point.x}, ${point.y})`); // 출력 : (10, 0)
    
    point.moveY(10);
    console.log(`(${point.x}, ${point.y})`); // 출력 : (10, 10)
    
    class Point3D extends Point {
        z: number;
    
        constructor(x: number = 0, y: number = 0, z: number = 0) {
            super(x, y);
            this.z = z;
        }
    
        moveZ(n: number): void {
            this.z += n
        }
    }
    
    const point3D = new Point3D();
    
    point3D.moveZ(10);
    console.log(`(${point3D.x}, ${point3D.y}, ${point3D.z})`); // 출력 : (0, 0, 10)

     

    7. 제네릭

    제네릭은 타입을 매개변수화하여 코드를 타입에 독립적이고 재사용 가능하게 만든다.

    // Queue (FIFO)
    class Queue<T> {
        private array: T[] = [];
    
        push(item: T) {
            this.array.push(item);
        }
        pop(): T | undefined {
            return this.array.shift();
        }
    }
    
    const numberQueue = new Queue<number>(); // 숫자 타입 다루는 큐 생성
    numberQueue.push(1);
    numberQueue.push(2);
    numberQueue.push(3);
    console.log(numberQueue); // 출력 : [1, 2, 3]
    
    console.log(numberQueue.pop()); // 출력 : 1
    
    const stringQueue = new Queue<string>(); // 문자열 타입 다루는 큐 생성
    stringQueue.push("한슬");
    stringQueue.push("스리");
    console.log(stringQueue); // 출력 : ["한슬", "스리"]

     

    8. Union(합집합, |) or Intersection(교집합, &)

    Union 시 아래와 같이 두 타입 Alias 중 일부를 사용하거나 모두를 사용해도 된다.

    Intersection 시 모든 속성이 병합된 타입, 즉 모두를 사용해야 한다.

    type Identify = {
        id: number | string;
        name: string;
    }
    
    type Contact = {
        name: string;
        email: string;
        phone: string;
    }
    
    type IdentifyOrContact = Identify | Contact;
    
    // 오직 Identify Alias 사용
    const id: IdentifyOrContact = {
        id: "1",
        name: "Three"
    }
    
    // 오직 Contact Alias 사용
    const contact: IdentifyOrContact = {
        name: "Three",
        email: "three@three.com",
        phone: "010-0000-0000"
    }
    
    // Identify + Contact 사용
    const test: IdentifyOrContact = {
        id: "2",
        name: "Three",
        email: "three@three.com",
        phone: "010-1111-1111"
    }

     

    9. 옵셔널 체인

    옵서녈 체인을 통해 null, undefined가  되어도 괜찮은 객체를 안전하게 처리할 수 있습니다.

    interface User {
        name: string;
        social?: {
            instagram: boolean;
            tiktok: boolean;
        }
    }
    
    let user: User;
    
    // user = { name: "Three", social: { instagram: true, tiktok: false } };
    // console.log(user.social?.instagram) // 출력 : true
    
    // user = { name: "Three" };
    // console.log(user.social?.instagram) // 출력 : undefined

     

     

    10. keyof

    interface User {
        name: string;
        age: number;
        email: string;
    }
    
    type UserKey = keyof User; // type UserKey = "name" | "age" | "email"

     

    11. readonly

    속성 변경 불가

     

    12. unknown

    typeof나 instanceof로 타입을 안전한 상태(타입 지정)로 만든 뒤

    변경하거나 대입하는 등의 처리를 할 수 있기 때문에 any 대신 사용합니다.

     

    13. 비동기 async / await

    // 비동기 함수 정의
    function fetchFromServer(id: string): Promise<{ success: boolean }> {
        // Promise를 사용하여 비동기적인 작업 수행
        return new Promise(resolve => {
            setTimeout(() => {
                // 비동기 작업 완료 후 resolve 호출
                resolve({ success: true });
            }, 100);
        });
    }
    
    // 비동기 처리를 포함하는 async function의 반환값 타입 : Promise
    async function asyncFunc(): Promise<string> {
        // fetchFromServer 호출 시 await 키워드를 사용하여 비동기 작업이 완료될 때까지 기다림
        const result = await fetchFromServer("temp");
        // 결과를 이용하여 문자열 생성 후 반환
        return `결과는 ${result.success}`;
    }
    
    // await 사용을 위해서는 async function 안에서 호출
    (async () => {
        // asyncFunc 호출 및 결과 출력
        const result = await asyncFunc();
        console.log(result);
    })();
    
    // Promise로 다룰 때는 아래와 같이 사용
    // asyncFunc 호출 후 then 메소드를 사용하여 결과 처리
    asyncFunc().then(result => console.log(result));
Designed by Tistory.