[Medium] Typescript tips

Jung taeWoong·2021년 10월 30일
0

typescript

목록 보기
11/11

Generics

  • any 타입은 무족건 피하라
  • 대부분의 시나리오에서 Generics은 유용하다
// Bad
type APIResponse = {
  items?: any[];
  item: any;
}

// Good
type APIResponse<T> = {
  items?: T[];
  item: T;
}

type User = {
  id: string;
}

const fetchCall = <T>(method: string, url: string): Promise<APIResponse<T>> => {
  // ...
}

export const getUser = (id: string): Promise<User> => {
  return fetchCall<User>(HttpMethod.GET, `/v1/user/${id}`)
    .then(({ item }) => item)
}

Keyof Type Operator

  • keyof를 사용함으로써 유니온타입을 따로 지정안해줘도 된다.
  • 키가 변경될때마다 유동적으로 변경되는 이점
    • 리팩토링의 도움이된다. (Union type으로 설정한경우 키값이 수정되면 이중작업 필요)
type ExpiryDateTime = {
  days: number;
  hours: number;
  minutes: number;
}

const expiryDateTime: ExpiryDateTime = {
  days: 0,
  hours: 0,
  minutes: 0,
}

const onChange = (
  key: keyof ExpiryDateTime, // days | hours | minutes
  val: number
) : void = {
  expiryDateTime[key] = val
}

Typeof Type Operator

  • typeof는 변수의 타입을 추출 가능
  • JavaScript의 typeof와 달리 TypeScript의 typeof는 type에서 사용하여 type으로 참조할 수 있습니다.
let foo = "bar";
let name: typeof foo; // string
const getHisOrHer = (val: number): "his" | "her" => {
  // ...
}

type HisOrHer = ReturnType<typeof getHisOrHer> // "his" | "her"

// OR

type GetHisOrHerFunc = (val: number) => "his" | "her"

const getHisOrHer: GetHisOrHerFunc = (val) => {
  // ...
}

type HisOrHer = ReturnType<GetHisOrHerFunc> // "his" | "her"

- getHisOrHer 반환 타입을 변경하면 HisOrHer 타입이 변경 사항을 따르게 됩니다. 
- 일회성 작업입니다.

Conditional Types

  • 개념은 JavaScript의 삼항 연산자 조건과 유사합니다.
  • 불행히도 세 번째 또는 그 이상의 옵션을 가질 수 없습니다.
type NumberId = {
  id: number;
};

type StringId = {
  id: string;
};

type StringOrNumber<T extends string | number> = T extends string
  ? StringId
  : NumberId

const getId = <T extends string | number>(val: T): StringOrNumber<T> => {
  //...
}

const s = getId("1")
// 문자열을 인수로 사용하면 StringId 타입 사용
const n = getId(2)
// 문자열을 숫자로 사용하면 NumberId 타입 사용

Mapped Types

  • 어려워서 나중에

Template Literal Types

  • 이 기능은 JavaScript의 템플릿 리터럴과 동일한 개념입니다.
  • 문자열 리터럴 위에 type을 빌드합니다.
type Locale = "zh" | "en" | "ms";
type Lang = `lang-${Locale}`;

// type Lang = "lang-zh" | "lang-en" | "lang-ms"

Utility Type

Last but not least, the utility types:

  • Pick<T, Keys> — Picking properties of key from the type
  • Omit<T, Keys> — The opposite of Pick , it takes all properties except Keys
  • Partial<T> — Similar to ? a.k.a optional , but you don’t have to make all the properties inside to be optional, because you might only need partial in a variable or function.
  • Required<T> — The opposite of Partial<T> , this will require all the properties include the optional one
  • Readonly<T> — The whole property would be immutable, and read-only
  • Record<Key, T> — I doesn’t recommend the use of object type in TypeScript, you will often get TS2339: Property 'x' does not exist on type 'object' . I always use Record<Key, T>as the replacement.
type TodoWithId = {
  readonly id: string;
  title: string;
  subtitle: null | string;
  description: string;
}

// Pick<T, Keys>
type Todo = Pick<TodoWithId, "title" | "subtitle" | "description">;
// Or
// Omit<T, Keys>
type Todo = Omit<TodoWithId, "id">

const t1: Todo = {
  title: "foo",
  subtitle: "bar",
  description: "",
};

// Partial<T>
const updateTodo = (todo: Todo, update: Partial<Todo>): Todo => {
  // ...
}
const t2 = updateTodo(t1, { description: "hello world" });

// Required<T>
const resetTodo = (todo: Todo, newTodo: Required<Todo>): Todo => {
  // ...
}
const t3 = resetTodo(t1, { description: "hello world" });
// Type '{ description: string; }' is missing the following properties from type 'Required<Todo>': title, subtitle

// Readonly<T>
const immutableTodo: Readonly<Todo> = t2;
immutableTodo.subtitle = ""
// TS2540: Cannot assign to 'subtitle' because it is a read-only property.

// Record<Key, T>
const obj: Record<string, Todo> = {
  t1: t1,
  t2: t2,
};

Bonus — Intellij based IDE

via GIPHY



  • JavaScript 코드베이스를 TypeScript 코드베이스로 마이그레이션하거나, 아무거나 사용하는 것을 좋아하는 코드베이스를 리팩토링하려고 할 때 이 기능이 구세주입니다.
profile
Front-End 😲

0개의 댓글