
1. 서론
Typescript는 타입선언 시 활용할 수 있는 여러가지 유틸리티 타입이라는 것을 제공한다. 유틸리티 타입은 어떤 임의의 타입을 제네릭으로 받아 여러가지 형태로 쉽게 변형할 수 있도록 만들어졌고 전역에서 사용 가능하다. 덕분에 간결한 코드로 타입 안정성이 보장된 인터페이스 설계가 가능하다.
Typescript는 현재(2022.10.11 기준)까지 22가지 유틸리티 타입을 제공한다. 종류가 많기 때문에 여러 포스트으로 나누어 작성하려고 한다. 본 포스트는 이전 포스트에서 다루지 않은 나머지 유틸리티 타입들에 대해 다뤘다.
이전 포스트 바로가기
[Typescript] 유틸리티 타입 - 1
1. 서론 Typescript는 타입선언 시 활용할 수 있는 여러가지 유틸리티 타입이라는 것을 제공한다. 유틸리티 타입은 어떤 임의의 타입을 제네릭으로 받아 여러가지 형태로 쉽게 변환할 수 있도록 만
blog.betaman.kr
본 포스트는 Typescript 공식 레퍼런스를 참고하여 작성됐다.
Documentation - Utility Types
Types which are globally included in TypeScript
www.typescriptlang.org
2. Parameters<Type>
Parameters<Type>은 Type이라는 함수 타입의 파라미터에 사용된 타입들을 튜플 타입으로 생성한다.
이때, Parameters<any>는 unknown Array를 반환하고, Parameters<string>이나 Parameters<Function> 처럼 함수 타입이 아니거나 (...args: any): any 시그니쳐와 일치하는 항목을 제공하지 않는 함수 타입은 에러가 발생하며 never 타입을 반환한다. Parameters<never>는 never를 반환한다.
declare function f1(arg: { a: number; b: string }): void; | |
type T0 = Parameters<() => string>; | |
// --> type T0 = [] | |
type T1 = Parameters<(s: string) => void>; | |
// --> type T1 = [s: string] | |
type T2 = Parameters<<T>(arg: T) => T>; | |
// --> type T2 = [arg: unknown] | |
type T3 = Parameters<typeof f1>; | |
// --> type T3 = [arg: {a: number; b: string;}] | |
type T4 = Parameters<any>; | |
// --> type T4 = unknown[] | |
type T5 = Parameters<never>; | |
// --> type T5 = never | |
type T6 = Parameters<string>; // <-- 에러 발생 | |
// --> type T6 = never | |
type T7 = Parameters<Function>; // <-- 에러 발생 | |
// --> type T7 = never |
3. ConstructorParameters<Type>
ConstructorParameters<Type>는 Type이라는 생성자 함수 타입의 파라미터에 사용된 타입들을 튜플 타입으로 생성한다.
type T0 = ConstructorParameters<ErrorConstructor>; | |
// --> type T0 = [message?: string | undefined] | |
type T1 = ConstructorParameters<FunctionConstructor>; | |
// --> type T1 = string[] | |
type T2 = ConstructorParameters<RegExpConstructor>; | |
// --> type T2 = [pattern: string | RegExp, flags?: string | undefined] | |
type T3 = ConstructorParameters<any>; | |
// --> type T3 = unknown[] | |
type T4 = ConstructorParameters<Function>; // <-- 에러 발생 | |
// --> type T4 = never | |
type T5 = ConstructorParameters<abstract new () => void>; // 추상클래스 생성자 타입 | |
// --> type T5 = [] | |
type T6 = ConstructorParameters<new () => void>; // 비추상클래스 생성자 타입 | |
// --> type T6 = [] | |
type T7 = ConstructorParameters<() => void>; // <-- 에러 발생 | |
// --> type T7 = never |
Parameters<Type>와의 차이점이라고 하면 Parameters<Type>의 Type은 모든 함수 타입이 들어갈 수 있지만, ConstructorParameters<Type>의 Type은 생성자 함수 타입만 들어갈 수 있다. 그래서 일반적인 함수 타입을 넣으면 에러가 발생하면서 never 타입을 반환하게 되고, 일반적인 함수 타입 앞에 new 키워드를 붙인 생성자 함수 타입은 정상적으로 튜플을 반환한다.
4. ReturnType<Type>
ReturnType<Type>은 Type이라는 함수 타입의 리턴 타입을 반환한다. Type이 함수 타입이 아니거나 (...args: any) => any 시그니쳐에 맞지 않는 함수 타입이라면 any를 반환하게 된다.
declare function f1(): { a: number; b: string }; | |
type T0 = ReturnType<() => string>; | |
// --> type T0 = string | |
type T1 = ReturnType<(s: string) => void>; | |
// --> type T1 = void | |
type T2 = ReturnType<<T>() => T>; | |
// --> type T2 = unknown | |
type T3 = ReturnType<<T extends U, U extends number[]>() => T>; | |
// --> type T3 = number[] | |
type T4 = ReturnType<typeof f1>; | |
// --> type T4 = {a: number; b: string;} | |
type T5 = ReturnType<any>; | |
// --> type T5 = any | |
type T6 = ReturnType<never>; | |
// --> type T6 = never | |
type T7 = ReturnType<string>; // <-- 에러 발생 | |
// --> type T7 = any | |
type T8 = ReturnType<Function>; // <-- 에러 발생 | |
// --> type T8 = any | |
5. InstanceType<Type>
InstanceType<Type>는 Type이라는 생성자 함수의 인스턴스 타입을 반환한다.
class C { | |
x = 0; | |
y = 0; | |
} | |
type T0 = InstanceType<typeof C>; | |
// --> type T0 = C | |
type T1 = InstanceType<any>; | |
// --> type T1 = any | |
type T2 = InstanceType<never>; | |
// --> type T2 = never | |
type T3 = InstanceType<string>; // <-- 에러 발생 | |
// --> type T3 = any | |
type T4 = InstanceType<Function>; // <-- 에러 발생 | |
// --> type T4 = any |
6. ThisParameterType<Type>
ThisParameterType<Type>은 Type이라는 함수 타입의 this 파라미터의 타입을 반환한다. 이때 this 파라미터가 없는 함수타입의 경우 unknown을 반환한다.
function toHex(this: Number) { | |
return this.toString(16); | |
} | |
function numberToString(n: ThisParameterType<typeof toHex>) { | |
return toHex.apply(n); | |
} | |
function testFunction(this: Number, str: string) {} | |
type toHexThisType = ThisParameterType<typeof toHex>; | |
// --> type toHexThisType = Number; | |
type testFunctionThisType = ThisParameterType<typeof testFunction>; | |
// --> type toHexThisType = Number; |
7. OmitThisParameter<Type>
OmitThisParameter<Type>은 Type에서 this 파라미터만 제거한 타입을 생성한다. 아래 예제를 보면 toHex 함수 선언시 명시했던 this가 noThisToHex 함수 타입의 파라미터에는 존재하지 않는 것을 확인할 수 있다.
function toHex(this: Number) { // --> function toHex(this: Number): string | |
return this.toString(16); | |
} | |
type noThisToHex = OmitThisParameter<typeof toHex>; | |
// --> type noThisToHex = () => string |
8. ThisType<Type>
ThisType<Type>은 어떠한 타입의 변형을 위해 사용한다기보단, 문맥적인 측면에서 this의 타입을 명시해주기 위해 사용하는 타입이다. 대신 이 타입을 사용하려면 tsconfig에서 noImplicitThis를 true로 설정하거나 커맨드 라인에서 플래그를 활성화해주어야 한다.

interface Post { | |
title: string, | |
getTitle: () => string, | |
} | |
function makeAPost(methods: ThisType<Post>) { | |
return {title: 'A', ...methods} as Post; | |
} | |
const a = makeAPost({ | |
getTitle() { | |
return this. | |
} | |
}); | |
console.log(a.getTitle()); // output --> 'A' |
위 예제에서 makeAPost의 파라미터로 사용되는 methods의 타입을 정의할때 기존 인터페이스에 ThisType<Type>을 감싸줌으로써, 인터페이스 내 모든 프로퍼티들의 this의 타입을 명시해줄 수 있다.
*makeAPost의 리턴 값은 새로운 객체를 생성하여 반환하는 것이기 때문에 타입단언이 필요했다.
9. Intrinsic String Manipulation Types
문자열 리터럴 타입의 문자열을 Upper, Lower, Capitalize, Uncapitalize 해주는 유틸리티 타입들이다.
type a = 'hello'; | |
type aUpper = Uppercase<a>; | |
// --> type aUpper = 'HELLO' | |
type b = 'HELLO'; | |
type bLower = Lowercase<b>; | |
// --> type bLower = 'hello' | |
type c = 'hello world'; | |
type cCapitalize = Capitalize<c>; | |
// --> type cCapitalize = 'Hello world' | |
type d = 'HELLO WORLD'; | |
type dUncapitalize = Uncapitalize<d>; | |
// --> type dUncapitalize = 'hELLO WORLD' |
'SW > Typescript' 카테고리의 다른 글
[Typescript] Javascript의 Pass by Reference와 Pass by Value (0) | 2022.10.25 |
---|---|
[Typescript] Chrome Extension에서 중단 없이 Interval 사용하기 (manifest v3) (0) | 2022.10.24 |
[Typescript] 유틸리티 타입 - 1 (0) | 2022.10.11 |
[Typescript] Svelte로 Chrome Extension 개발하기 (0) | 2022.10.07 |
[Typescript] Chrome Extension manifest v3 (0) | 2022.10.07 |