반응형
a. Partial<T>
- T의 모든 프로퍼티들을 옵셔널하게 만드는 유틸리티 타입
b. Readonly<T>
- T의 모든 프로퍼티들을 읽기 전용(readonly)으로 만드는 유틸리티 타입
interface Palette {
[key: string] : string
}
const gray: Readonly<Palette> = {
'001': '#111111',
'002': '#999999',
}
// frozen 객체의 프로퍼티에 재할당하려고 하는 경우
function freeze<T>(obj: T): Readonly<T>;
c. Record<K,T>
- 타입 T의 프로퍼티의 집합 K로 타입을 구성
// 객체의 key 와 value의 타입을 따로따로 정의 가능
interface PageInfo {
title: string;
}
type Page = 'home' | 'about' | 'contact';
const x: Record<Page, PageInfo> = {
about: { title: 'about' },
contact: { title: 'contact' },
home: { title: 'home' },
};
d. Pick<T,K>
- T에서 프로퍼티 K의 집합을 선택해 타입을 구성
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, 'title' | 'completed'>;
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
};
e. Omit<T,K>
- T에서 모든 프로퍼티를 선택한 다음 K를 제거한 타입을 구성
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, 'description'>;
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
}
// yup TestContext 내의 parent 의 타입을 정의
// 기존 타입과 겹치는 타입을 제거 후 추가된 프로퍼티의 타입을 추가
interface ThumbnailTestContext extends Omit<TestContext, 'parent'> {
parent: Thumbnail
}
type ThumbnailTestContext = Omit<TestContext, 'parent'> & {parent: Thumbnail}
f. Exclude<T,U>
- T에서 U에 할당할 수 있는 모든 속성을 제외한 타입을 구성
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | number | (() => void), Function>; // string | number
g. Extract<T,U>
- T에서 U에 할당 할 수 있는 모든 속성을 추출하여 타입을 구성
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () => void
h. NonNullable<T>
- T에서 null과 undefined를 제외한 타입을 구성
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
// NonNullable 을 Exclude 유틸을 사용해서 구현할 수도 있다.
type NonNullable2<T> = Exclude<T, undefined | null>
i. Parameters<T>
- 함수 타입 T의 매개변수 타입들의 튜플 타입을 구성
declare function getSomethingActive(info: {id: string, state: boolean}): void
type Params = Parameters<typeof getSomethingActive>;
// [{id: string, state: boolean}]
-> infer 이 Parameters 와 같은 유틸을 만들 때 유용하게 사용됨
j. ConstructorParameters<T>
- 생성자 함수 타입의 모든 매개변수 타입을 추출
- Parameters 와 비슷하지만 생성자임을 확인하기 위한 abstract new 가 추가로 붙었다.
class User {
constructor (name: string, tier: 'GOLD' | 'SILVER') {}
}
const muzi = new User('Muzi', 'GOLD');
const a: ConstructorParameters<typeof User> = ['Muzi', 'GOLD'];
const b: ConstructorParameters<typeof User> = ['Lion']; // type error..
k. ReturnType<T>
- 함수 T의 반환 타입으로 구성된 타입
declare function f1(): { a: number, b: string }
type T0 = ReturnType<typeof f1>; // { a: number, b: string }
l. InstanceType<T>
- 생성자 함수 타입 T의 인스턴스 타입으로 구성된 타입
class User {
x = 'x'
constructor(public name: string) {}
}
class User2 {
x = 0;
constructor(public name: string) {}
}
const user: InstanceType<typeof User> = new User('name');
const user2: InstanceType<typeof User> = new User2('name');
m. Required<T>
- T의 모든 프로퍼티가 필수로 설정된 타입을 구성
- -? : Mapping Modifiers 의 하나로 옵셔널을 제거 (링크)
interface Props {
a?: number;
b?: string;
};
const obj: Props = { a: 5 }; // 성공
const obj2: Required<Props> = { a: 5 }; // 오류: 프로퍼티 'b'가 없습니다
n. ThisParameterType
- 함수 타입의 this 매개변수의 타입, 혹은 함수 타입에 this 매개변수가 없을 경우
- unknown 을 추출합니다
- --strictFunctionTypes가 활성화되었을 때만 올바르게 동작함
function toHex(this: Number) {
return this.toString(16);
}
function numberToString(n: ThisParameterType<typeof toHex>) {
return toHex.apply(n);
}
o. OmitThisParameter
- 함수 타입에서 'this' 매개변수를 제거
- --strictFunctionTypes가 활성화되었을 때만 올바르게 동작함
function getAge(this: typeof cat) {
return this.age;
}
// 기존 데이터
const cat = {
age: 12 // Number
};
getAge.call(cat); // 12
// 새로운 데이터
const dog = {
age: '13' // String
};
getAge.call(dog); // TS2345: Argument of type '{ age: string; }' is not assignable to parameter of type '{ age: number; }'.
const getAgeForDog: OmitThisParameter<typeof getAge> = getAge;
getAgeForDog.call(dog); // '13'
p. ThisType<T>
- 이 유틸리티는 변형된 타입을 반환하지 않는 대신, 문맥적 this타입에 표시하는 역할을 함
- --noImplicitThis플래그를 사용해야 함
interface IUser {
name: string,
getName: () => string
}
function makeNeo(methods: ThisType<IUser>) {
// ThisType이 타입을 반환하지 않기 때문에 타입 단언을 사용하여 타입이 추론되게끔 하였다.
return { name: 'Neo', ...methods } as IUser;
}
const neo = makeNeo({
getName() {
return this.name;
}
});
neo.getName(); // Neo
느낀점
- 유틸타입을 적극적으로 사용하면 좀 더 명시적인 타이핑이 가능할 것 같다.
- extends, infer 의 쓰임새에 대해서 좀 더 이해하게 되었다. 특히 infer 의 경우 언제 쓸지 정말 궁금했는데 이럴 때 쓰는거구나 하고 느끼게 됨
- Mapping Modifiers 을 처음 알게 되었다.
출처
반응형