Skip to content

Latest commit

Β 

History

History
331 lines (236 loc) Β· 9.15 KB

utility-types.md

File metadata and controls

331 lines (236 loc) Β· 9.15 KB

μ†Œκ°œ (Introduction)

TypeScriptλŠ” 곡톡 νƒ€μž… λ³€ν™˜μ„ μš©μ΄ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄ λͺ‡ 가지 μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ„ μ œκ³΅ν•©λ‹ˆλ‹€. 이런 μœ ν‹Έλ¦¬ν‹°λ“€μ€ μ „μ—­μœΌλ‘œ μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€.

λͺ©μ°¨ (Table of contents)

Partial<T>

T의 λͺ¨λ“  ν”„λ‘œνΌν‹°λ₯Ό μ„ νƒμ μœΌλ‘œ λ§Œλ“œλŠ” νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€. 이 μœ ν‹Έλ¦¬ν‹°λŠ” 주어진 νƒ€μž…μ˜ λͺ¨λ“  ν•˜μœ„ νƒ€μž… 집합을 λ‚˜νƒ€λ‚΄λŠ” νƒ€μž…μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

예제 (Example)
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',
});

Readonly<T>

T의 λͺ¨λ“  ν”„λ‘œνΌν‹°λ₯Ό 읽기 μ „μš©(readonly)으둜 μ„€μ •ν•œ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€, 즉 μƒμ„±λœ νƒ€μž…μ˜ ν”„λ‘œνΌν‹°λŠ” μž¬ν• λ‹Ήν•  수 μ—†μŠ΅λ‹ˆλ‹€.

예제 (Example)
interface Todo {
    title: string;
}

const todo: Readonly<Todo> = {
    title: 'Delete inactive users',
};

todo.title = 'Hello'; // 였λ₯˜: 읽기 μ „μš© ν”„λ‘œνΌν‹°μ— μž¬ν• λ‹Ήν•  수 μ—†μŒ

이 μœ ν‹Έλ¦¬ν‹°λŠ” λŸ°νƒ€μž„μ— μ‹€νŒ¨ν•  ν• λ‹Ή ν‘œν˜„μ‹μ„ λ‚˜νƒ€λ‚Ό λ•Œ μœ μš©ν•©λ‹ˆλ‹€.(예, frozen 객체의 ν”„λ‘œνΌν‹°μ— μž¬ν• λ‹Ή ν•˜λ €κ³  ν•˜λŠ” 경우)

Object.freeze
function freeze<T>(obj: T): Readonly<T>;

Record<K,T>

νƒ€μž… T의 ν”„λ‘œνΌν‹°μ˜ 집합 K둜 νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€. 이 μœ ν‹Έλ¦¬ν‹°λŠ” νƒ€μž…μ˜ ν”„λ‘œνΌν‹°λ“€μ„ λ‹€λ₯Έ νƒ€μž…μ— λ§€ν•‘μ‹œν‚€λŠ” 데 μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€.

예제 (Example)
interface PageInfo {
    title: string;
}

type Page = 'home' | 'about' | 'contact';

const x: Record<Page, PageInfo> = {
    about: { title: 'about' },
    contact: { title: 'contact' },
    home: { title: 'home' },
};

Pick<T,K>

Tμ—μ„œ ν”„λ‘œνΌν‹° K의 집합을 선택해 νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
interface Todo {
    title: string;
    description: string;
    completed: boolean;
}

type TodoPreview = Pick<Todo, 'title' | 'completed'>;

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
};

Omit<T,K>

Tμ—μ„œ λͺ¨λ“  ν”„λ‘œνΌν‹°λ₯Ό μ„ νƒν•œ λ‹€μŒ Kλ₯Ό μ œκ±°ν•œ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
interface Todo {
    title: string;
    description: string;
    completed: boolean;
}

type TodoPreview = Omit<Todo, 'description'>;

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
};

Exclude<T,U>

Tμ—μ„œ U에 ν• λ‹Ήν•  수 μžˆλŠ” λͺ¨λ“  속성을 μ œμ™Έν•œ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
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

Extract<T,U>

Tμ—μ„œ U에 ν• λ‹Ή ν•  수 μžˆλŠ” λͺ¨λ“  속성을 μΆ”μΆœν•˜μ—¬ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
type T0 = Extract<"a" | "b" | "c", "a" | "f">;  // "a"
type T1 = Extract<string | number | (() => void), Function>;  // () => void

NonNullable<T>

Tμ—μ„œ null κ³Ό undefinedλ₯Ό μ œμ™Έν•œ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
type T0 = NonNullable<string | number | undefined>;  // string | number
type T1 = NonNullable<string[] | null | undefined>;  // string[]

Parameters<T>

ν•¨μˆ˜ νƒ€μž… T의 λ§€κ°œλ³€μˆ˜ νƒ€μž…λ“€μ˜ νŠœν”Œ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
declare function f1(arg: { a: number, b: string }): void
type T0 = Parameters<() => string>;  // []
type T1 = Parameters<(s: string) => void>;  // [string]
type T2 = Parameters<(<T>(arg: T) => T)>;  // [unknown]
type T4 = Parameters<typeof f1>;  // [{ a: number, b: string }]
type T5 = Parameters<any>;  // unknown[]
type T6 = Parameters<never>;  // never
type T7 = Parameters<string>;  // 였λ₯˜
type T8 = Parameters<Function>;  // 였λ₯˜

ConstructorParameters<T>

ConstructorParameters<T> νƒ€μž…μ€ μƒμ„±μž ν•¨μˆ˜ νƒ€μž…μ˜ λͺ¨λ“  λ§€κ°œλ³€μˆ˜ νƒ€μž…μ„ μΆ”μΆœν•  수 있게 ν•΄μ€λ‹ˆλ‹€. λͺ¨λ“  λ§€κ°œλ³€μˆ˜ νƒ€μž…μ„ κ°€μ§€λŠ” νŠœν”Œ νƒ€μž…(Tκ°€ ν•¨μˆ˜κ°€ μ•„λ‹Œ 경우 never)을 μƒμ„±ν•©λ‹ˆλ‹€.

예제 (Example)
type T0 = ConstructorParameters<ErrorConstructor>;  // [(string | undefined)?]
type T1 = ConstructorParameters<FunctionConstructor>;  // string[]
type T2 = ConstructorParameters<RegExpConstructor>;  // [string, (string | undefined)?]

ReturnType<T>

ν•¨μˆ˜ T의 λ°˜ν™˜ νƒ€μž…μœΌλ‘œ κ΅¬μ„±λœ νƒ€μž…μ„ λ§Œλ“­λ‹ˆλ‹€.

예제 (Example)
declare function f1(): { a: number, b: string }
type T0 = ReturnType<() => string>;  // string
type T1 = ReturnType<(s: string) => void>;  // void
type T2 = ReturnType<(<T>() => T)>;  // {}
type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>;  // number[]
type T4 = ReturnType<typeof f1>;  // { a: number, b: string }
type T5 = ReturnType<any>;  // any
type T6 = ReturnType<never>;  // any
type T7 = ReturnType<string>;  // 였λ₯˜
type T8 = ReturnType<Function>;  // 였λ₯˜

InstanceType<T>

μƒμ„±μž ν•¨μˆ˜ νƒ€μž… T의 μΈμŠ€ν„΄μŠ€ νƒ€μž…μœΌλ‘œ κ΅¬μ„±λœ νƒ€μž…μ„ λ§Œλ“­λ‹ˆλ‹€.

Example
class C {
    x = 0;
    y = 0;
}

type T0 = InstanceType<typeof C>;  // C
type T1 = InstanceType<any>;  // any
type T2 = InstanceType<never>;  // any
type T3 = InstanceType<string>;  // 였λ₯˜
type T4 = InstanceType<Function>;  // 였λ₯˜

Required<T>

T의 λͺ¨λ“  ν”„λ‘œνΌν‹°κ°€ ν•„μˆ˜λ‘œ μ„€μ •λœ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.

예제 (Example)
interface Props {
    a?: number;
    b?: string;
};

const obj: Props = { a: 5 }; // 성곡

const obj2: Required<Props> = { a: 5 }; // 였λ₯˜: ν”„λ‘œνΌν‹° 'b'κ°€ μ—†μŠ΅λ‹ˆλ‹€

ThisParameterType

ν•¨μˆ˜ νƒ€μž…μ˜ this λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…, ν˜Ήμ€ ν•¨μˆ˜ νƒ€μž…μ— this λ§€κ°œλ³€μˆ˜κ°€ 없을 경우 unknown을 μΆ”μΆœν•©λ‹ˆλ‹€.

유의: 이 νƒ€μž…μ€ --strictFunctionTypesκ°€ ν™œμ„±ν™”λ˜μ—ˆμ„ λ•Œλ§Œ μ˜¬λ°”λ₯΄κ²Œ λ™μž‘ν•©λ‹ˆλ‹€. #32964λ₯Ό μ°Έκ³ ν•˜μ„Έμš”.

예제 (Example)
function toHex(this: Number) {
    return this.toString(16);
}

function numberToString(n: ThisParameterType<typeof toHex>) {
    return toHex.apply(n);
}

OmitThisParameter

ν•¨μˆ˜ νƒ€μž…μ—μ„œ 'this' λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

유의: 이 νƒ€μž…μ€ --strictFunctionTypesκ°€ ν™œμ„±ν™”λ˜μ—ˆμ„ λ•Œλ§Œ μ˜¬λ°”λ₯΄κ²Œ λ™μž‘ν•©λ‹ˆλ‹€. #32964λ₯Ό μ°Έκ³ ν•˜μ„Έμš”.

예제 (Example)
function toHex(this: Number) {
    return this.toString(16);
}

// `bind`의 λ°˜ν™˜ νƒ€μž…μ€ 이미 `OmitThisParameter`을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€, μ΄λŠ” 단지 예제λ₯Ό μœ„ν•œ κ²ƒμž…λ‹ˆλ‹€.
const fiveToHex: OmitThisParameter<typeof toHex> = toHex.bind(5);

console.log(fiveToHex());

ThisType<T>

이 μœ ν‹Έλ¦¬ν‹°λŠ” λ³€ν˜•λœ νƒ€μž…μ„ λ°˜ν™˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹ , λ¬Έλ§₯적 thisνƒ€μž…μ— ν‘œμ‹œν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€. 이 μœ ν‹Έλ¦¬ν‹°λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„  --noImplicitThis ν”Œλž˜κ·Έλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λŠ” 것을 μœ μ˜ν•˜μ„Έμš”.

예제 (Example)
// --noImplicitThis 둜 컴파일

type ObjectDescriptor<D, M> = {
    data?: D;
    methods?: M & ThisType<D & M>;  // λ©”μ„œλ“œ μ•ˆμ˜ 'this νƒ€μž…μ€ D & M μž…λ‹ˆλ‹€.
}

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
    let data: object = desc.data || {};
    let methods: object = desc.methods || {};
    return { ...data, ...methods } as D & M;
}

let obj = makeObject({
    data: { x: 0, y: 0 },
    methods: {
        moveBy(dx: number, dy: number) {
            this.x += dx;  // κ°•ν•˜κ²Œ νƒ€μž…μ΄ 정해진 this
            this.y += dy;  // κ°•ν•˜κ²Œ νƒ€μž…μ΄ 정해진 this
        }
    }
});

obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);

μœ„ μ˜ˆμ œμ—μ„œ, makeObject의 인자둜 λ„˜κ²¨μ§€λŠ” methods κ°μ²΄λŠ” ThisType<D & M>λ₯Ό ν¬ν•¨ν•œ λ¬Έλ§₯적 νƒ€μž…μ„ 가지고 있고, λ”°λΌμ„œ methods 객체의 λ©”μ„œλ“œ μ•ˆμ— this νƒ€μž…μ€ { x: number, y: number } & { moveBy(dx: number, dy: number): number }μž…λ‹ˆλ‹€. method ν”„λ‘œνΌν‹°μ˜ νƒ€μž…μ΄ μΆ”λ‘ μ˜ λŒ€μƒμ΄λ©° λ™μ‹œμ— λ©”μ„œλ“œ μ•ˆμ˜ this νƒ€μž…μ˜ 좜처인 것을 μ£Όλͺ©ν•˜μ„Έμš”.

ThisType<T> 마컀 μΈν„°νŽ˜μ΄μŠ€λŠ” 단지 lib.d.ts에 μ„ μ–Έλœ 빈 μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€. 객체 λ¦¬ν„°λŸ΄μ˜ λ¬Έλ§₯적 νƒ€μž…μœΌλ‘œ μΈμ‹λ˜λŠ” 것을 λ„˜μ–΄, κ·Έ μΈν„°νŽ˜μ΄μŠ€λŠ” 빈 μΈν„°νŽ˜μ΄μŠ€μ²˜λŸΌ λ™μž‘ν•©λ‹ˆλ‹€.