์ ํธ๋ฆฌํฐ ํ์ ์ ์ด์ฉํ๋ฉด ํ์ ๋ณํ์ ๋ ์ฝ๊ฒ ํ ์ ์๊ธฐ์ ์์๋๋ฉด ์ข๋ค.
์ ํธ๋ฆฌํฐ ํ์ | ์ค๋ช | ํ์ ์ธ์ |
---|---|---|
Awaited | ๋น๋๊ธฐ ํจ์๋ Promise๋ฅผ ๊ธฐ๋ค๋ ธ์ ๋, ํด๋น ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ ๊ฐ์ธ Type์ ํด๋นํ๋ ํ์ ์ ๊ฐ์ ธ์ด | <TYPE> |
Partial | ๋ถ๋ถ์ | <TYPE> |
Required | ํ์์ | <TYPE> |
Readonly | ์ฝ๊ธฐ ์ ์ฉ | <TYPE> |
Record | KEY-์์ฑ, TYPE-์์ฑ๊ฐ์ ํ์ ํํ๋ก ์๋ก์ด ํ์ ๋ฐํ (์ธํฐํ์ด์ค) | <KEY, TYPE> |
Omit | TYPE์์ KEY๋ก ์์ฑ์ ์๋ต | <TYPE, KEY> |
Pick | TYPE์์ KEY๋ก ์์ฑ์ ์ ํ | <TYPE, KEY> |
Exclude | ์ ์ธ. TYPE1์์ TYPE2๋ฅผ ์ ์ธ (์ ๋์ธ) | <TYPE1, TYPE2> |
Extract | ๊ต์งํฉ์. TYPE1์์ TYPE2๋ฅผ ์ถ์ถ (์ ๋์ธ) | <TYPE1, TYPE2> |
NonNullable | null๊ณผ undefined๋ฅผ ์ ์ธ (์ ๋์ธ) | <TYPE> |
Parameters | TYPE์ ๋งค๊ฐ๋ณ์ ํ์ ์ ์๋ก์ด ํํ ํ์ ์ผ๋ก ๋ฐํ (ํจ์, ํํ) | <TYPE> |
ReturnType | TYPE์ ๋ฐํ ํ์ ์ ์๋ก์ด ํ์ ์ผ๋ก ๋ฐํ (ํจ์) | <TYPE> |
InstanceType | TYPE์ ์ธ์คํด์ค ํ์ ์ ๋ฐํ (ํด๋์ค) | <typeof TYPE> |
๋น๋๊ธฐ ํจ์๋ Promise๋ฅผ ๊ธฐ๋ค๋ ธ์ ๋, ํด๋น ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ ๊ฐ์ธ Type์ ํด๋นํ๋ ํ์ ์ ๊ฐ์ ธ์จ๋ค.
async function fetchData(): Promise<string> {
return "Hello, World!";
}
async function example() {
const result: Awaited<ReturnType<typeof fetchData>>;
return result;
}
example();
๋ถ๋ถ์
interface User {
name: string
age: number
}
type UserPartial = Partial<User>
const a : UserPartial = {
name: "tata" // age๋ฅผ ์ ์ง ์์๋ ๋๋ค.
}
console.log(a.name) // tata
ํ์์
interface User {
name: string
age?: number
}
type UserPartial = Required<User>
const a : UserPartial = {
name: "tata",
age: 7 // ์ ์ง ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฌ๋ค.
}
console.log(a.name) // tata
console.log(a.age) // 7
์ฝ๊ธฐ ์ ์ฉ์ด๋ผ ์์ ์ด ๋ถ๊ฐํ๋ค.
interface User {
name: string
age?: number
}
type UserPartial = Readonly<User>
const a : UserPartial = {
name: "tata",
age: 7
}
// a.age = "chimmy" ์ด๋ ๊ฒ ์์ ์ด ๋ถ๊ฐํจ.
<KEY, TYPE>
KEY๋ฅผ ์์ฑ์ผ๋ก, TYPE์ ์์ฑ ๊ฐ์ ํ์ ์ผ๋ก ๊ฐ์ง๋ ๊ฐ์ฒด ํ์ ์ ์์ฑํ๋ค.
type Fruit = 'apple' | 'banana' | 'orange';
type FruitMap = Record<Fruit, number>;
const fruitCount: FruitMap = {
apple: 10,
banana: 20,
orange: 15
};
<TYPE, KEY>
TYPE์์ KEY๋ก ์์ฑ์ ์๋ต
interface User {
name: string
age: number
}
type UserWithoutAge = Omit<User, 'age'>;
const a: UserWithoutAge = {
name: 'tata',
};
console.log(a.name) // tata
<TYPE, KEY>
TYPE์์ KEY๋ก ์์ฑ์ ์ ํ
interface User {
id: number;
name: string;
age: number;
email: string;
}
type UserPick = Pick<User, 'name' | 'email'>;
const a: UserPick = {
name: 'tata',
email: 'tata@example.com'
};
console.log(a.name) // tata
console.log(a.email) // tata@example.com
<TYPE1, TYPE2>
<ํ์
, ์ ์ธํ ์ ๋์จ ํ์
>
์ ์ธ. TYPE1์์ TYPE2๋ฅผ ์ ์ธ (์ ๋์ธ)
type T1 = number | string | boolean;
type T2 = string | boolean;
type T3 = Exclude<T1, T2>; // T3 ํ์
์ number์ด๋ค.
-----
type T1 = 'a' | 'b' | 'c' | 'd';
type T2 = 'a' | 'c';
type T3 = Exclude<T1, T2>; // T3 ํ์
์ 'b' | 'd'์ด๋ค.
<TYPE1, TYPE2>
<ํ์
, ๊ต์งํฉ์ํฌ ์ ์๋ ์ ๋์จ ํ์
>
๊ต์งํฉ์. TYPE1์์ TYPE2๋ฅผ ์ถ์ถ (์ ๋์ธ)
type T1 = number | string | boolean;
type T2 = string | boolean;
type T3 = Extract<T1, T2>; // T3 ํ์
์ string, boolean์ด๋ค.
-----
type T1 = 'a' | 'b' | 'c' | 'd';
type T2 = 'a' | 'c';
type T3 = Extract<T1, T2>; // T3 ํ์
์ 'a' | 'c'์ด๋ค.
NonNullable
null๊ณผ undefined๋ฅผ ์ ์ธ (์ ๋์ธ)
type T1 = string | number | null | undefined;
type T2 = Extract<T1, string | null>; // 'string' | null
type T3 = NonNullable<T2>; // 'string'
TYPE์ ๋งค๊ฐ๋ณ์ ํ์ ์ ์๋ก์ด ํํ ํ์ ์ผ๋ก ๋ฐํ (ํจ์, ํํ)
type MyFunctionType = (a: number, b: string, c: boolean) => void;
type MyParametersType = Parameters<MyFunctionType>;
// [number, string, boolean]
const a: MyParametersType = [12, "12", true]
console.log(a) // [12, "12", true]
-----
const test = (a: number, b: number) => {
return 'test';
}
type Example = Parameters<typeof test>
// [number, number]
const a: Example = [12, 13]
console.log(a) // [12, 13]
TYPE์ ๋ฐํ ํ์ ์ ์๋ก์ด ํ์ ์ผ๋ก ๋ฐํ (ํจ์)
// 1.
type R1 = ReturnType<() => string>
const a = (): R1 => {
return '123'
}
console.log(a()) // "123"
-----
// 2.
const test = () => {
return 'test';
}
type R1 = ReturnType<typeof test>;
const b = (): R1 => {
return '123'
}
console.log(b()) // "123"
<typeof TYPE>
TYPE์ ์ธ์คํด์ค ํ์
์ ๋ฐํ (ํด๋์ค)
typeof
๋ฅผ ๊ผญ ๋ถ์ฌ์ฃผ์ด์ผ ํ๋ค.
class MyClass {
name: string;
constructor(name: string) {
this.name = name;
}
}
type MyType = InstanceType<typeof MyClass>; // MyClass
const instance: MyType = new MyClass("hello");
console.log(instance); // MyClass { name: 'hello' }
๋น๊ตํ๊ธฐ. boolean์ ๋ฐํ
// Equal<T, U>: T์ U๊ฐ ๊ฐ์ ํ์
์ธ์ง ๋น๊ต (๊ฐ์ผ๋ฉด true, ๋ค๋ฅด๋ฉด false)
type Equal<T, U> = (<G>() => G extends T ? 1 : 2) extends
(<G>() => G extends U ? 1 : 2) ? true : false;
type Test1 = Equal<1, 1>; // true
type Test2 = Equal<1, 2>; // false
type Test3 = Equal<string, string>; // true
type Test4 = Equal<{ a: number }, { a: number }>; // true
type Test5 = Equal<{ a: number }, { a: string }>; // false
Expect๋ ์ฃผ๋ก ํ ์คํธ ํ๊ฒฝ์์ ํ์ ์ด ์์ํ ๋๋ก ๋์ํ๋์ง ๊ฒ์ฆํ ๋ ์ฌ์ฉ๋๋ ์ ํธ๋ฆฌํฐ ํ์ ์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก Expect๋ Equal<T, U>๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ค. TypeScript ์์ฒด์๋ Expect๋ผ๋ ๋ด์ฅ ํ์ ์ด ์์ง๋ง, ํ์ ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(@type-challenges/utils) ๋ฑ์์ ์ ๊ณตํ๊ฑฐ๋ ์ง์ ์ ์ํด์ ์ฌ์ฉํ ์ ์๋ค.
type Expect<T extends true> = T;
// ์ ์ ๋์ (ํ์
์ด ๊ฐ์)
type Test1 = Expect<Equal<1, 1>>; // ์ ์
type Test2 = Expect<Equal<string, string>>; // ์ ์
type Test3 = Expect<Equal<{ a: number }, { a: number }>>; // ์ ์
// ์ค๋ฅ ๋ฐ์ (ํ์
์ด ๋ค๋ฆ)
type Test4 = Expect<Equal<1, 2>>; // ํ์
์ค๋ฅ ๋ฐ์
type Test5 = Expect<Equal<{ a: number }, { a: string }>>; // ํ์
์ค๋ฅ ๋ฐ์
๐ Utility Types
๐ typescript ํ๊ธ ๋ฒ์ญ