하위 태스크 1

인덱스드 액세스 타입

객체 프로퍼티 타입 추출

src/indexed-access.ts:

interface Post {
    author: {
        name: string;
    };
}
 
type Author = Post["author"]; // { name: string; }

하위 태스크 2

중첩 프로퍼티 추출

Post[“author”][“name”] 형태

src/indexed-access.ts:

// ...
 
type AuthorName = Post["author"]["name"]; // string

하위 태스크 3

배열 요소 타입 추출

PostList[number] 형태

src/indexed-access.ts:

// ...
 
type PostList = Post[];
 
type PostItem = PostList[number]; // Post

하위 태스크 4

튜플 요소 타입 추출

Tuple[0], Tuple[1] 형태

src/indexed-access.ts:

// ...
 
type Tuple = [Post, AuthorName, number];
 
type ElementOne = Tuple[0]; // Post
type ElementTwo = Tuple[1]; // string
type ElementThree = Tuple[2]; // number

하위 태스크 5

keyof 연산자

객체 키를 유니온 타입으로 추출

src/keyof-operator.ts:

interface Person {
    name: string;
    age: number;
    job: string;
}
 
type PersonKeys = keyof Person;
 
const invalidPersonKey: PersonKeys = hairColor; // Cannot find name 'hairColor'.

하위 태스크 6

keyof + 제네릭

타입 안전한 프로퍼티 접근 함수

src/keyof-operator.ts:

// ...
 
function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}
 
const person: Person = {
    name: "김석현",
    age: 15,
    job: "학생",
};
 
const age = getProperty(person, "age");
console.log(age); // 15

하위 태스크 7 ~ 9

맵드 타입 기본

[K in keyof T] 형태 기본 사용

Partial 구현

맵드 타입으로 Partial 만들기

Readonly 구현

맵드 타입으로 Readonly 만들기

src/mapped-types.ts:

interface User {
    id: number;
    name: string;
    organization: string;
}
 
type PartialUser = {
    [K in keyof User]?: User[K];
};
 
type ReadonlyUser = {
    readonly [K in keyof User]: User[K];
};
 
type RequiredUser = {
    [K in keyof PartialUser]-?: PartialUser[K];
};

하위 태스크 10

템플릿 리터럴 타입

문자열 패턴 타입 정의

src/template-literals.ts:

type Color = "red" | "green" | "yellow" | "blue" | "white";
 
type Theme = `bg-${Color}`;
 
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
 
type ApiEndPoint = `/api/v2/${string}`;
 
type ApiRoute = `${HttpMethod} ${ApiEndPoint}`;