타입스크립트 모르는 것만 모아서 정리

제이밍·2023년 7월 7일
2
post-thumbnail

Utility Types

Awaited (TypeScript 4.5 ↑)

Awaited<Type>

async function getUser(): Promise<{ 
    id: number; 
    name: string 
}> {
    return { id: 1, name: 'John Doe' };
}
  
type User = Awaited<ReturnType<typeof getUser>>;
  
async function printUser(): Promise<void> {
    const user: User = await getUser();
    console.log(user);
}
  
printUser();
  • Promise<?> 형태의 T 타입을 전달받아, 해당 Promise가 반환하는 리턴값의 타입을 반환한다.
    async ~ await의 await 키워드와 유사한 기능을 담당한다.

타입제거 exclude vs omit (TypeScript 2.8 ↑)

exclude는 여러개의 타입이 함께 존재하는 유니언 타입에서 특정 타입을 제거하는 유틸리티 타입이다.

type T0 = Exclude<'a' | 'b' | 'c', 'a'>
// type T0 = "b" | "c"
type T1 = Exclude<'a' | 'b' | 'c', 'a' | 'b'>
// type T1 = "c"
type T2 = Exclude<string | number | (() => void), Function>
// type T2 = string | number

omit 은 객체 타입 (interface 등)에서 특정 키를 기준으로 생략하여 타입을 내려주는 유틸리티 타입이다.

interface Todo {
  title: string
  description: string
  completed: boolean
  createdAt: number
}

// description을 제외
type TodoPreview = Omit<Todo, 'description'>

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

Extract<Type, Union> (TypeScript 2.8 ↑)

type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// type T0 = "a"

type T1 = Extract<string | number | (() => void), Function>;
// type T1 = () => void
                                     
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; x: number }
  | { kind: "triangle"; x: number; y: number };
 
type T2 = Extract<Shape, { kind: "circle" }>
  
  //type T2 = {
  // kind: "circle";
  // radius: number;
}

NonNullable<Type> (TypeScript 2.8 ↑)

타입에서 Null, undefined 를 제외한 타입을 갖는다.

type T0 = NonNullable<string | number | undefined>;
     
type T1 = NonNullable<string[] | null | undefined>;

Parameters<Type>

함수 유형 Type의 매개변수에 사용된 유형에서 튜플 유형을 구성합니다.

declare function f1(arg: { a: number; b: string }): void;
 
type T0 = Parameters<() => string>;   
//type T0 = []

type T1 = Parameters<(s: string) => void>;
//type T1 = [s: string]

type T2 = Parameters<<T>(arg: T) => T>;   
//type T2 = [arg: unknown]

배열에서 Union type 추출하기

Create a Union type from an Array in TypeScript

// 👇️ const sizes: readonly ["small", "medium", "large"]
const sizes = ['small', 'medium', 'large'] as const;

// 👇️ type SizesUnion = "small" | "medium" | "large"
type SizesUnion = typeof sizes[number];

웹메인 활용 예시

const vendorTypeArray = ['smartorder', 'store-general', 'store-ticket'] as const;
type SlugType = typeof vendorTypeArray[number];

타입의 연산

interface isDataString<T extends boolean> {
   data: T extends true ? string : number;
   isString: T;
}

const str: isDataString<true> = {
   data: '홍길동', // String
   isString: true,
};

const num: isDataString<false> = {
   data: 9999, // Number
   isString: false,
};

조건부 타입

// X - 선언 시 에러가 발생한다.
interface isDataString2<T extends true ? string : number> {
   data: T
} 

// O
interface isDataString<T extends boolean> {
   data: T extends true ? string : number;
   isString: T;
}

const str: isDataString<true> = {
   data: '홍길동', // String
   isString: true,
};

const num: isDataString<false> = {
   data: 9999, // Number
   isString: false,
};

분산적 조건부 타입

제네릭 타입 위에서 조건부 타입은 유니온 타입을 만나게 되면 분산적으로 동작합니다.

이를 분산적 조건부 타입이라고 합니다.

분산 조건부 타입은 타입을 인스턴스화하는 중에 자동으로 유니언 타입으로 분산됩니다.

type Diff<T, U> = T extends U ? never : T; 

// 1. 첫 번째 과정
type T30 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;

// 2. 두 번째 과정
type T30 = 
  | ("a" extends "a" | "c" | "f" ? never : T)
  | ("b" extends "a" | "c" | "f" ? never : T)
  | ("c" extends "a" | "c" | "f" ? never : T)
  | ("d" extends "a" | "c" | "f" ? never : T);

// 3. 최종 결과
type T30 = "b" | "d"

REFERENCE

타입스크립트도 조건문을 쓸 수 있다??!!? ㄴ(°0°)ㄱ

profile
모르는것은 그때그때 기록하기

0개의 댓글