https://www.typescriptlang.org/docs/handbook/utility-types.html
Documentation - Utility Types
Types which are globally included in TypeScript
www.typescriptlang.org
위 원문을 번역한다.
Partial<Type>
: 특정 object의 일부분만 가질 때 사용한다. 항목을 지정하지 않고 그저 일부이면 가능.
interface Todo {
title : string ;
description: string ;
}
function updateTodo (todo: Todo, fieldsToUpdate: Partial<Todo> ) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title : "organize desk" ,
description : "clear clutter" ,
};
const todo2 = updateTodo(todo1, {
description : "throw out trash" ,
});
console .log(updateTodo(todo1, todo2));
===========
[LOG]: {
"title" : "organize desk" ,
"description" : "throw out trash"
}
위 소스에서 Partial<Todo>는 Todo 인터페이스가 가진 항목의 일부를 가진 object이다.
Required<Type>
: 특정 object의 모든 항목을 반드시 가져야 한다.
interface Props {
a?: number ;
b?: string ;
}
const obj: Props = { a : 5 };
const obj2: Required<Props> = { a : 5 };
==================
Errors in code
Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>' .
위 소스에서 Required<Props>로 선언된 obj2는 optional로 선언한 b항목이 없어서 에러가 난다.
Readonly<Type>
: 처음 선언된 값을 변경할 수 없다.
interface Todo {
title : string ;
}
const todo: Readonly<Todo> = {
title : "Delete inactive users" ,
};
todo.title = "Hello" ;
================
Errors in code
Cannot assign to 'title' because it is a read-only property.
위 소스에서 Readonly<Todo> todo로 선언되어 있기 때문에 todo안의 항목의 값을 바꾸려고 할 경우 에러가 난다.
이 타입은 Object.freeze 함수 내부에서 사용되고 있다.
function freeze <Type >(obj: Type ): Readonly <Type > ;
----------------
const obj = {
prop : 42
};
Object .freeze(obj);
obj.prop = 33 ;
console .log(obj.prop);
Record<Keys, Type>
: 키가 Key이고 값이 Type인 객체 타입
interface CatInfo {
age : number ;
breed: string ;
}
type CatName = "miffy" | "boris" | "mordred" ;
const cats: Record<CatName, CatInfo> = {
miffy : { age : 10 , breed : "Persian" },
boris : { age : 5 , breed : "Maine Coon" },
mordred : { age : 16 , breed : "British Shorthair" },
};
console .log(cats.boris);
==============
[LOG]: {
"age" : 5 ,
"breed" : "Maine Coon"
}
참고로 Record는 인덱스 시그니처(Index Signature)는 대괄호로 객체를 접근하는 방식으로도 표현가능하다.
interface CatInfo {
age : number ;
breed: string ;
}
type CatName = "miffy" | "boris" | "mordred" ;
const cats: Record<CatName, CatInfo> = {
miffy : { age : 10 , breed : "Persian" },
boris : { age : 5 , breed : "Maine Coon" },
mordred : { age : 16 , breed : "British Shorthair" },
};
const catss: {[name: string ] : CatInfo} = {
boris : { age : 5 , breed : "Maine Coon" },
}
console .log(cats.boris);
console .log(catss.boris);
다만 인덱스 시그니처는 문자열 리터럴을 Key로 사용하는 경우 오류가 발생한다. 위 catss를 `catss: {[name: CatName : CatInfo}` 로 선언하면 에러가 난다.
Pick<Type, Keys>
: 어떤 object의 항목 중 일부만 골라서 사용 가능하다. 비슷한 부분집합 형태의 interface를 또 만들 필요가 없어진다.
interface Todo {
title : string ;
description: string ;
completed: boolean ;
}
type TodoPreview = Pick<Todo, "title" | "completed" >;
const todo: TodoPreview = {
title : "Clean room" ,
completed : false ,
};
선택한 항목 외에 다른 것을 더 넣거나 덜 넣으면 에러가 난다.
Omit<Type, Keys>
: Pick과 반대 기능으로 특정 항목만 제하고 사용할 수 있다.
interface Todo {
title : string ;
description: string ;
completed: boolean ;
createdAt: number ;
}
type TodoPreview = Omit<Todo, "description" >;
const todo: TodoPreview = {
title : "Clean room" ,
completed : false ,
createdAt : 1615544252770 ,
};
const todo2: TodoPreview = {
title : "Clean room" ,
createdAt : 1615544252770 ,
};
type TodoInfo = Omit<Todo, "completed" | "createdAt" >;
const todoInfo: TodoInfo = {
title : "Pick up kids" ,
description : "Kindergarten closes at 5pm" ,
};
제한 항목 이외의 것을 더 넣거나 덜 넣으면 에러가 난다.
Exclude<UnionType, ExcludedMembers>
: 앞의 것 빼기 뒤의 것을 타입으로 갖는다.
type T0 = Exclude<"a" | "b" | "c" , "a" >;
const test1: T0 = "a" ;
const test2: T0 = "b" ;
const test3: T0 = "d" ;
type T1 = Exclude<"a" | "b" | "c" , "a" | "b" >;
type T2 = Exclude<string | number | (() => void ), Function >;
const test4: T2 = function ( ) {
console .log("this" )
}
const test6: T2 = function (a: string ):string {
return "hello " + a;
};
type T3 = Exclude<string | number | Function , Function >;
const test5: T3 = function ( ) {
console .log("this" )
}
제한 타입 이외의 값을 가지면 에러가 난다.
Extract<Type, Union>
: 앞의 타입 중 뒤의 것만 추출한 것을 타입으로 가진다.
type T0 = Extract<"a" | "b" | "c" , "a" | "f" >;
const test:T0 = "f" ;
const test2:T0 = "b" ;
const test3:T0 = "a" ;
type T1 = Extract<string | number | (() => void ) | ((args: string ) => string ), Function >;
const test4:T1 = function (a: string ):string {
return 'hello ' + a;
}
const test5:T1 = function ( ):string {
return 'hello' ;
}
const test6:T1 = function (a: string ) {
console .log("test " + a)
}
const test7:T1 = "guest"
위 소스에서 T1은 string, number, 인자 없는 함수, 인자 있고 return 있는 함수 중 함수의 형태만 타입으로 가질 수 있다.
test6은 return 이 없는 함수고 test7은 string이라 에러가 난다.
NonNullable<Type>
: Type에 들어오는 타입 중 null, undefined를 제한 타입만 가능하다
type T0 = NonNullable<string | number | undefined >;
type T1 = NonNullable<string [] | null | undefined >;
Parameters<Type>
: 함수의 파라미터를 타입으로 리턴한다.
declare function f1 (arg: { a: number ; b: string } ): void ;
type T0 = Parameters<() => string >;
type T1 = Parameters<(s: string ) => void >;
type T2 = Parameters<<T>(arg: T ) => T>;
type T3 = Parameters<typeof f1>;
type T4 = Parameters<any >;
type T5 = Parameters<never >;
type T6 = Parameters<string >;
type T7 = Parameters<Function >;
위 소스에서 T6, T7은 '(...args: any) => any '의 형식이 아니라서 에러가 난다. 즉 Parameters가 인자로 받을 수 있는 것은 모든 파라미터를 인자로 받고 결괏값으로 모든 값을 리턴하는, 사실상 모든 함수가 된다.
ConstructorParameters<Type>
: 생성자를 갖는 함수 타입의 생성자 파라미터를 리턴한다. 함수가 아니라면 never를 리턴한다. 위 Parameters와 비슷하지만 생성자 파라미터로 한정한다.
type T0 = ConstructorParameters<ErrorConstructor>;
type T1 = ConstructorParameters<FunctionConstructor>;
type T2 = ConstructorParameters<RegExpConstructor>;
type T3 = ConstructorParameters<any >;
type T4 = ConstructorParameters<Function >;
============
class Person {
private _firstname: string
private _lastname: string
constructor (firstname: string , lastname: string ) {
this ._firstname = firstname
this ._lastname = lastname
}
}
type typeIs = ConstructorParameters<typeof Person>;
let personConstructionArgs: typeIs = ['first' , 'last' ]
ReturnType<Type>
: 함수의 리턴타입을 가져온다.
declare function f1 ( ): { a: number ; b: string };
type T0 = ReturnType<() => string >;
type T1 = ReturnType<(s: string ) => void >;
type T2 = ReturnType<<T>() => T>;
type T3 = ReturnType<<T extends U, U extends number []>() => T>;
type T4 = ReturnType<typeof f1>;
type T5 = ReturnType<any >;
type T6 = ReturnType<never >;
type T7 = ReturnType<string >;
type T8 = ReturnType<Function >;
InstanceType<Type>
: 생성자로 초기화된 인스턴스 타입을 리턴한다.
class C {
x = 0 ;
y = 0 ;
}
type T0 = InstanceType<typeof C>;
const test :T0 = {x : 1 , y : 3 , z : 2 }
type T1 = InstanceType<any >;
type T2 = InstanceType<never >;
type T3 = InstanceType<string >;
type T4 = InstanceType<Function >;
ThisParameterType<Type>
: 함수 타입의 this 파라미터의 type을 가져온다. this를 가지지 않는 함수 타입이면 unknown을 반환한다.
function toHex (this : Number ) {
return this .toString(16 );
}
type T = ThisParameterType<typeof toHex>;
function numberToString (n: ThisParameterType<typeof toHex> ) {
return toHex.apply(n);
}
OmitThisParameter<Type>
: 타입의 this 파라미터를 무시한다. 타입에 this가 없으면 그냥 Type이다. 있으면 this가 없는 Type 이 만들어진다.
function toHex (this : Number ) {
return this .toString(16 );
}
console .log(toHex.call(2 ));
type T = OmitThisParameter<typeof toHex>;
const fiveToHex: T = toHex.bind(16 );
console .log(fiveToHex());