WeniVooks

검색

타입스크립트 베이스캠프

조건부 타입

1. 조건부 타입 이해하기

1.1 기본 조건부 타입

조건부 타입은 JavaScript의 if문처럼 타입을 조건에 따라 다르게 지정할 수 있게 해줍니다. 기본적인 형태는 타입 extends 조건 ? 참일때타입 : 거짓일때타입입니다.

type IsNumber<T> = T extends number ? '숫자입니다' : '숫자가 아닙니다';
 
// 사용 예시
type Result1 = IsNumber<number>;  // '숫자입니다'
type Result2 = IsNumber<string>;  // '숫자가 아닙니다'
 
// 실제 사용해보기
let value1: Result1 = '숫자입니다'; // 다른 값을 넣으면 에러 발생
let value2: Result2 = '숫자가 아닙니다';
 
console.log(value1);
console.log(value2);
type IsNumber<T> = T extends number ? '숫자입니다' : '숫자가 아닙니다';
 
// 사용 예시
type Result1 = IsNumber<number>;  // '숫자입니다'
type Result2 = IsNumber<string>;  // '숫자가 아닙니다'
 
// 실제 사용해보기
let value1: Result1 = '숫자입니다'; // 다른 값을 넣으면 에러 발생
let value2: Result2 = '숫자가 아닙니다';
 
console.log(value1);
console.log(value2);

앞서 배운 것을 활용하여 배열인지 아닌지 확인하는 타입을 만들어봅시다.

type IsArray<T> = T extends any[] ? '배열입니다' : '배열이 아닙니다';
 
// 사용 예시
type CheckNumbers = IsArray<number[]>;  // '배열입니다'
type CheckString = IsArray<string>;     // '배열이 아닙니다'
 
// 실제 사용 예시
function processInput<T>(input: T): IsArray<T> {
    if (Array.isArray(input)) {
        return '배열입니다' as IsArray<T>;
    }
    return '배열이 아닙니다' as IsArray<T>;
}
 
console.log(processInput([1, 2, 3]));      // '배열입니다'
console.log(processInput("안녕하세요"));    // '배열이 아닙니다'
type IsArray<T> = T extends any[] ? '배열입니다' : '배열이 아닙니다';
 
// 사용 예시
type CheckNumbers = IsArray<number[]>;  // '배열입니다'
type CheckString = IsArray<string>;     // '배열이 아닙니다'
 
// 실제 사용 예시
function processInput<T>(input: T): IsArray<T> {
    if (Array.isArray(input)) {
        return '배열입니다' as IsArray<T>;
    }
    return '배열이 아닙니다' as IsArray<T>;
}
 
console.log(processInput([1, 2, 3]));      // '배열입니다'
console.log(processInput("안녕하세요"));    // '배열이 아닙니다'
1.2 infer 키워드

infer는 타입을 추론할 때 사용합니다.

type GetReturnType<T> = T extends () => infer R ? R : never;
 
// 간단한 함수들
function getMessage() {
    return "안녕하세요";
}
 
function getNumber() {
    return 42;
}
 
// 사용 예시
type MessageType = GetReturnType<typeof getMessage>;  // string
type NumberType = GetReturnType<typeof getNumber>;    // number
 
// 실제 활용
const message: MessageType = "안녕하세요";    // OK
const number: NumberType = 42;               // OK
type GetReturnType<T> = T extends () => infer R ? R : never;
 
// 간단한 함수들
function getMessage() {
    return "안녕하세요";
}
 
function getNumber() {
    return 42;
}
 
// 사용 예시
type MessageType = GetReturnType<typeof getMessage>;  // string
type NumberType = GetReturnType<typeof getNumber>;    // number
 
// 실제 활용
const message: MessageType = "안녕하세요";    // OK
const number: NumberType = 42;               // OK

사용자 입력이 올바른 형식인지 확인하는 예제를 살펴봅시다.

type UserInput<T> = T extends string | number 
    ? '유효한 입력입니다' 
    : '문자나 숫자만 입력해주세요';
 
// 사용 예시
function validateInput<T>(input: T): UserInput<T> {
    if (typeof input === 'string' || typeof input === 'number') {
        return '유효한 입력입니다' as UserInput<T>;
    }
    return '문자나 숫자만 입력해주세요' as UserInput<T>;
}
 
// 실제 사용
console.log(validateInput("안녕"));   // '유효한 입력입니다'
console.log(validateInput(42));      // '유효한 입력입니다'
console.log(validateInput(true));    // '문자나 숫자만 입력해주세요'
type UserInput<T> = T extends string | number 
    ? '유효한 입력입니다' 
    : '문자나 숫자만 입력해주세요';
 
// 사용 예시
function validateInput<T>(input: T): UserInput<T> {
    if (typeof input === 'string' || typeof input === 'number') {
        return '유효한 입력입니다' as UserInput<T>;
    }
    return '문자나 숫자만 입력해주세요' as UserInput<T>;
}
 
// 실제 사용
console.log(validateInput("안녕"));   // '유효한 입력입니다'
console.log(validateInput(42));      // '유효한 입력입니다'
console.log(validateInput(true));    // '문자나 숫자만 입력해주세요'

2. 연습문제

아래 요구사항을 만족하는 코드를 작성하세요.

  1. 타입이 배열인 경우 요소 타입을 반환해주세요.
  2. 타입이 배열이 아닌 경우 never를 반환해주세요.

3. 연습문제 해답

type ArrayElementType<T> = T extends Array<infer E> ? E : never;
 
// 사용 예제
type NumberArrayElement = ArrayElementType<number[]>; // number
type StringArrayElement = ArrayElementType<string[]>; // string
type NeverType = ArrayElementType<string>; // never
type ArrayElementType<T> = T extends Array<infer E> ? E : never;
 
// 사용 예제
type NumberArrayElement = ArrayElementType<number[]>; // number
type StringArrayElement = ArrayElementType<string[]>; // string
type NeverType = ArrayElementType<string>; // never
3.5 비동기4장 부록