조건부 타입
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. 연습문제
아래 요구사항을 만족하는 코드를 작성하세요.
- 타입이 배열인 경우 요소 타입을 반환해주세요.
- 타입이 배열이 아닌 경우 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