반응형
문제 번역
왜 Default Generic Arguments이 필요할까요 ?
기술적으로 말하자면, 어떤 프로그램도 무조건 기본 파라미터가 필요하지 않습니다. 이건 개발자를 위한 편의기능이에요.
가끔 특정 파라미터를 위한 값을 생각하고 있고, 라이브러리 사용자에게 반복적으로 같은 값을 제공하도록 강요하고 싶지 않을때가 있습니다. 이때 Default Generic Arguments는 유용합니다.
어떻게 Default Type Arguments를 만들 수 있을까요 ?
첫번째 : 함수의 기본값에 대해서 다시 살펴보기
일반적인 로깅함수를 살펴보겠습니다. 이 함수는 함상 로그를 위해 message가 필요하지만, log level은 옵션으로 되기를 원합니다.
type LogLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical';
const log = (message: string, level: LogLevel = 'info') => {
// application logic
};
log('this has an explicit debug log level', 'debug');
log('this has an implicit info debug level');
제네릭 타입에서도 이러한 처리를 할 수 있습니다 ! 함수와 제네릭 타입의 유사점이기도 합니다.
Default Generic Arguments
type Log<Message, Level = 'info'> = {
message: Message;
level: Level;
};
type ExplicitDebugLog = Log<'explicit debug', 'debug'>;
type ImplicitInfo = Log<'implicit info'>;
매우 비슷해보이지 않나요 ? 함수의 기본 파라미터에 적용되는 규칙들이 타입에서도 적용됩니다. 예시로 필수 파라미터 뒤에 기본값 파라미터를 놓을 수 없습니다.
하나 주목할만한 예외에는 자바스크립트 함수의 기본 인자에 undefined
처럼 작동하는 Typescript 값은 없다는 점입니다.
const greet = (name = 'Stranger') => {
console.log(`Hello ${name}!`);
};
greet(); // Hello Stranger!
greet(undefined); // Hello Stranger!
greet('Mr. Monkey'); // Hello Mr. Monkey!
TypeScript에서는 never나 unknown 또는 any를 제공하더라도 기본값 대신 그 값이 삽입됩니다.
Solving This Challenge
목표는 올바른 기본 인수를 가진 몇 가지 타입을 만드는 것입니다.
두 번째 타입인 TSConfig는 조금 어려울 수 있지만, 막히면 아래의 작은 힌트를 참고하세요:
작은 힌트
- 리터럴 객체를 매개변수 기본값으로 사용하세요.
- indexed types을 사용하세요.
- 발생하는 오류는 generic constraint이 없어서 발생합니다.
문제
type ApiRequest = unknown;
type TSConfig = unknown;
이것을
import { Expect, Equal } from 'type-testing';
type test_ApiRequest_explicitPost = Expect<
Equal<ApiRequest<string, 'POST'>, { data: string; method: 'POST' }>
>;
type test_ApiRequest_implicitGet = Expect<
Equal<ApiRequest<number>, { data: number; method: 'GET' }>
>;
type test_TSConfig_default = Expect<Equal<TSConfig, { strict: true }>>;
type test_TSConfig_true = Expect<Equal<TSConfig<{ strict: true }>, { strict: true }>>;
type test_TSConfig_false = Expect<Equal<TSConfig<{ strict: false }>, { strict: false }>>;
type test_TSConfig_boolean = Expect<Equal<TSConfig<{ strict: boolean }>, { strict: boolean }>>;
이 조건에 맞춰야하는 문제입니다.
문제 풀이
type ApiRequest<T extends string | number, U = 'GET'> = { data : T; method : U }
type TSConfig<T extends { strict : boolean } = { strict : true }> = T;
제네릭에도 기본값이 된다는 것을 처음 알았다...!
반응형