
View on GitHub: https://tsch.js.org/15
배열 T를 사용하고 마지막 요소를 반환하는 제네릭 Last<T>를 구현합니다.
예시
type arr1 = ["a", "b", "c"];
type arr2 = [3, 2, 1];
type tail1 = Last<arr1>; // expected to be 'c'
type tail2 = Last<arr2>; // expected to be 1
type Last<T extends any[]> = T extends [...infer Rest, infer LastElement]
? LastElement
: never;
View on GitHub: https://tsch.js.org/16
배열 T를 사용해 마지막 요소를 제외한 배열을 반환하는 제네릭 Pop<T>를 구현합니다.
예시
type arr1 = ["a", "b", "c", "d"];
type arr2 = [3, 2, 1];
type re1 = Pop<arr1>; // expected to be ["a", "b", "c"];
type re2 = Pop<arr2>; // expected to be [3, 2];
type Pop<T extends any[]> = T extends [...infer Rest, infer Last] ? Rest : [];
View on GitHub: https://tsch.js.org/20
Type the function PromiseAll that accepts an array of PromiseLike objects, the returning value should be Promise<T> where T is the resolved result array.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise<string>((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
// expected to be `Promise<[number, 42, string]>`
const p = PromiseAll([promise1, promise2, promise3] as const);
type Awaited<T> = T extends Promise<infer R> ? Awaited<R> : T;
declare function PromiseAll<T extends any[]>(
values: readonly [...T]
): Promise<{
[K in keyof T]: Awaited<T[K]>;
}>;
에러 케이스
declare function PromiseAll<T extends any[]>(
values: T
): Promise<{ [K in keyof T]: T[K] extends Promise<infer U> ? U : T[K] }>;
PromiseAll 함수는 배열의 각 요소를 Promise로 감싸서 반환하는 함수T는 any[]로 받고, 이를 튜플로(readonly)로 변환하기 위해 readonly [...T]를 사용Promise로 감싸서 반환하기 위해 Promise<{ [K in keyof T]: Awaited<T[K]>; }>를 사용{ [K in keyof T]: Awaited<T[K]> }는 배열의 각 요소를 순회하며 키를 추출하고, 각 요소를 Awaited<T[K]>로 변환하여 반환Awaited<T[K]>는 T[K]가 Promise라면 Promise의 내부 타입을 추출하고, 그렇지 않다면 T[K]를 반환values에 readonly [...T]가 가능한 이유는?
T extends any[]에서 T는 배열이지만 튜플이 될 수도 있고, 일반 배열이 될 수도 있음readonly [...T]를 사용하여 튜플로 변환declare function Example<T extends any[]>(values: readonly [...T]): T;
declare function Example2<T extends any[]>(values: T): T;
const test1 = Example([1, 2, 3]); // T = [number, number, number] (튜플)
const test2 = Example2([1, 2, 3]); // T = number[] (일반 배열)
readonly [...T]에 맞춰 T를 튜플로 유추하려고 시도함values가 일반 배열(number[])이면 TypeScript는 가능한 한 readonly 속성을 유지하려고 함T는 [number, number, number]처럼 튜플로 추론됨readonly 옵션을 붙여주지 않으면 Example2처럼 일반 배열로 추론됨왜 Awaited가 필요한가?
T[K] extends Promise<infer U> ? U : T[K]를 사용하면 오류 발생extends)를 사용할 때, T가 유니온(A | B)이면 각각 개별적으로 평가한 후, 결과를 다시 유니온으로 합침T[K] 자체가 유니온 타입이기 때문에(이 문제에서는 number | Promise<number>), T[K]가 리턴될 경우 number | Promise<number>로 추론되어 오류 발생Awaited<T[K]>를 사용하여 T[K]가 리턴될 경우 number로 추론되도록 함View on GitHub: https://tsch.js.org/62
때때로 유니온 타입의 특정 속성을 기준으로 조회할 수도 있습니다.
이 챌린지에서는 유니온 타입 Cat | Dog에서 공통으로 사용하는 type 필드를 기준으로 해당하는 타입을 얻고자 합니다. 다시 말해서, 다음 예시에서는 LookUp<Cat | Dog, 'dog'>으로 Dog 타입을, LookUp<Cat | Dog, 'cat'>으로 Cat 타입을 얻을 수 있습니다.
interface Cat {
type: "cat";
breeds: "Abyssinian" | "Shorthair" | "Curl" | "Bengal";
}
interface Dog {
type: "dog";
breeds: "Hound" | "Brittany" | "Bulldog" | "Boxer";
color: "brown" | "white" | "black";
}
type MyDogType = LookUp<Cat | Dog, "dog">; // 기대되는 결과는 `Dog`입니다.
type LookUp<U, T> = U extends { type: T } ? U : never;
U를 분배법칙을 이용해 타입 조회U가 { type: T } 형태를 포함하는지 확인U를 반환never 반환View on GitHub: https://tsch.js.org/106
정확한 문자열 타입이고 시작 부분의 공백이 제거된 새 문자열을 반환하는 TrimLeft<T>를 구현하십시오.
type trimed = TrimLeft<" Hello World ">; // expected to be 'Hello World '
type TrimLeft<S extends string> = S extends `${" " | "\n" | "\t"}${infer Rest}`
? TrimLeft<Rest>
: S;
S가 " " | "\n" | "\t"로 시작하는지 확인S에서 시작 부분의 공백을 제거한 새 문자열(Rest)을 반환S를 그대로 반환View on GitHub: https://tsch.js.org/108
정확한 문자열 타입이고 시작 부분의 공백이 제거된 새 문자열을 반환하는 Trim<T>를 구현하십시오.
type trimmed = Trim<" Hello World ">; // expected to be 'Hello World'
type TrimLeft<S extends string> = S extends `${" " | "\n" | "\t"}${infer Rest}`
? TrimLeft<Rest>
: S;
type TrimRight<S extends string> = S extends `${infer Rest}${" " | "\n" | "\t"}`
? TrimRight<Rest>
: S;
type Trim<S extends string> = TrimRight<TrimLeft<S>>;
TrimLeft<S> 활용해 문자열 S에서 시작 부분의 공백을 제거한 새 문자열을 반환TrimRight<S>를 정의해 문자열 S에서 끝 부분의 공백을 제거한 새 문자열을 반환Trim<S>: TrimLeft<S>와 TrimRight<S>를 조합하여 문자열 S에서 양쪽 끝의 공백을 제거한 새 문자열을 반환