조아마시

쓸모 있는 상세페이지 만들기

웹개발/typescript

[타입스크립트] 타입추론

joamashi 2024. 9. 2. 16:12

타입 추론이란?

타입스크립트에서 타입 추론이란, 개발자가 명시적으로 변수의 타입을 지정하지 않아도 컴파일러가 코드 컨텍스트를 분석하여 변수의 타입을 자동으로 추론하는 기능입니다. 이는 개발 생산성을 높이고 코드 가독성을 향상시키는 데 큰 도움이 됩니다.

왜 타입 추론이 중요할까요?

  • 개발 생산성 향상: 반복적인 타입 선언을 줄여 개발 속도를 높입니다.
  • 코드 가독성 향상: 자연스러운 코드 작성이 가능해져 코드 이해를 쉽게 합니다.
  • 오류 조기 발견: 컴파일 시점에 타입 오류를 잡아내어 실행 시 예기치 못한 오류를 방지합니다.

타입 추론이 일어나는 경우

  • 변수 초기화:
    let message = 'Hello, TypeScript!'; // message는 string 타입으로 추론
    let count = 42; // count는 number 타입으로 추론
  • 함수의 반환 값:
    function greet(name: string): string {
        return 'Hello, ' + name + '!'; // 반환 값은 string 타입으로 추론
    }
  • 배열:
    let numbers: number[] = [1, 2, 3]; // numbers는 number[] 타입으로 추론
    let strings: string[] = ['hello', 'world']; // strings는 string[] 타입으로 추론
  • 객체:
    let person = {
        name: 'Alice',
        age: 30
    }; // person은 { name: string, age: number } 타입으로 추론
  • 제네릭:
    function identity<T>(arg: T): T {
        return arg;
    }
    let output = identity('myString'); // output은 string 타입으로 추론

복잡한 타입 추론

  • 유니온 타입:
    let value: string | number = 'hello';
    value = 42;
    
  • 인터섹션 타입:
    interface Person {
        name: string;
    }
    interface Loggable {
        log(): void;
    }
    let personAndLoggable: Person & Loggable = {
        name: 'John',
        log: () => { console.log('Hello'); }
    };
    
  • 조건부 타입:
    type TypeName<T> = T extends string ? 'string' : 'number';
    type T1 = TypeName<string>; // 'string'

타입 추론의 한계

  • any 타입:
    let notSure: any = 4;
    notSure = 'maybe a string instead';
    any 타입은 모든 타입을 허용하지만, 타입 안전성을 잃을 수 있습니다.
  • 컨텍스트 부족: 복잡한 코드나 동적 타입 변환이 발생하는 경우, 컴파일러가 정확한 타입을 추론하지 못할 수 있습니다.

타입스크립트 타입 추론 심층 탐구 및 예시 코드 상세 설명

1. 다양한 상황에서의 타입 추론 예시

1.1 복잡한 객체와 배열

interface Person {
  name: string;
  age: number;
  address?: {
    city: string;
    zipCode: number;
  };
}

const people: Person[] = [
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25, address: { city: 'Seoul', zipCode: 12345 } },
];
  • people 배열은 Person 인터페이스 타입으로 추론됩니다.
  • address 프로퍼티는 선택적(optional)이므로 일부 객체에는 존재하지 않을 수 있습니다.
  • 배열 내 각 요소는 Person 인터페이스의 구조를 따릅니다.

1.2 함수의 매개변수와 반환값

function greet(name: string, age?: number): string {
  return `Hello, ${name}! You are ${age ?? 'unknown'} years old.`;
}
  • greet 함수의 name 매개변수는 string 타입으로, age 매개변수는 number | undefined 타입으로 추론됩니다.
  • ?? 연산자는 nullish coalescing 연산자로, age가 null 또는 undefined일 때 기본값 'unknown'을 사용합니다.
  • 함수의 반환값은 string 타입으로 추론됩니다.

1.3 제네릭과 조건부 타입

function identity<T>(arg: T): T {
  return arg;
}

type TypeName<T> = T extends string ? 'string' : 'number';

const output = identity<string>('myString'); // output은 string 타입
const typeName = TypeName<number>; // typeName은 'number' 타입
  • identity 함수는 제네릭 함수로, 어떤 타입의 값이든 받아서 그대로 반환합니다.
  • TypeName은 조건부 타입으로, 입력 타입이 string이면 'string', 그렇지 않으면 'number'를 반환합니다.

1.4 튜플

const myTuple: [string, number] = ['hello', 42];
  • myTuple은 튜플 타입으로, 순서대로 string과 number 타입의 값을 가집니다.

2. 타입 추론의 심층적인 내용

  • 컨텍스트 기반 추론: 함수 내부, 조건문, 반복문 등 다양한 컨텍스트에서 타입이 추론됩니다.
  • 타입 가드: typeof, instanceof 등을 사용하여 타입을 확인하고 더 정확한 타입 추론을 할 수 있습니다.
  • 타입 앨리어스: 복잡한 타입에 별칭을 부여하여 코드 가독성을 높이고 재사용성을 향상시킵니다.
  • 인터섹션 타입: 여러 타입의 공통된 속성을 가진 타입을 정의합니다.
  • 유니온 타입: 여러 타입 중 하나일 수 있는 타입을 정의합니다.
  • 매핑된 타입: 객체의 프로퍼티 타입을 일괄적으로 변환합니다.

3. 왜 타입 추론이 중요한가요?

  • 코드 안정성: 컴파일 시점에 타입 오류를 잡아내어 실행 시 예기치 못한 오류를 방지합니다.
  • 개발 생산성 향상: 반복적인 타입 선언을 줄여 개발 속도를 높입니다.
  • 코드 가독성 향상: 자연스러운 코드 작성이 가능해져 코드 이해를 쉽게 합니다.
  • IDE 지원 향상: 타입 정보를 기반으로 자동 완성, 리팩토링 등 다양한 기능을 제공합니다.
728x90