TypeScript Advanced

33155 단어 typescripttypescript

1. Type vs Interface 구현 차이점

{
  type PositionType = {
    x: number;
    y: number;
  };
  interface PositionInterface {
    x: number;
    y: number;
  }

  // object ★
  const obj1: PositionType = {
    x: 1,
    y: 1,
  };
  const obj2: PositionInterface = {
    x: 1,
    y: 1,
    z: 1,
  };

  // class ★ 
  class Pos1 implements PositionType {
    x: number;
    y: number;
  }
  class Pos2 implements PositionInterface {
    x: number;
    y: number;
  }

  // Extends : interface 는 extends를 이용하여 확장 
  interface ZPositionInterface extends PositionInterface {
    z: number;
  }

 //& 연산자로 합칠 수 있음. 
  type ZPositionType = PositionType & { z: number };

  // 😆 only interfaces can be merged. type은 불가능하다. 
  interface PositionInterface {
    z: number;
  }

  // type PositionType {
  // }

  // 😆 Type aliases can use computed properties (ONLY) 
  type Person = {
    name: string;
    age: number;
  };
  type Name = Person['name']; // string

  type NumberType = number;
// union type 도 type으로만 가능! 
  type Direction = 'left' | 'right';
}

2. Interface vs Type?

interface : 누군가가 class를 통해 구현할 사람을 위한 규격서
type : data의 타입을 그저 결정하는 것

3. Utility type

3-1. Index type

{
  const obj = {
    name: 'ellie',
  };
  obj.name; // ellie
  obj['name']; // ellie

  type Animal = {
    name: string;
    age: number;
    gender: 'male' | 'female';
  };

  type Name = Animal['name']; // string
  const text: Name = 'hello'; //if 숫자, error 

  type Gender = Animal['gender']; //'male' | 'female'

  type Keys = keyof Animal; // 'name' | 'age' | 'gender' -> union type
  const key: Keys = 'gender';

  type Person = {
    name: string;
    gender: Animal['gender'];
  };
  const person: Person = {
    name: 'ellie',
    gender: 'male',
  };
}

3-2. map type

{
  type Video = {
    title: string;
    author: string;
  };
  // [1, 2].map(item => item * item); // [1, 4]

  type Optional<T> = {
    [P in keyof T]?: T[P]; // for...in과 비슷한 문법 
  };

  type ReadOnly<T> = {
    readonly [P in keyof T]: T[P];
  };
  type VideoOptional = Optional<Video>;

  type Animal = {
    name: string;
    age: number;
  };
  const animal: Optional<Animal> = {
    name: 'dog',
  };
  animal.name = 'ellie';

  const video: ReadOnly<Video> = {
    title: 'hi',
    author: 'ellie',
  };

  // type VideoOptional = {
  //   title?: string;
  //   author?: string;
  // };

  // type VideoReadOnly = {
  //   readonly title: string;
  //   readonly author: string;
  // };

  type Nullable<T> = { [P in keyof T]: T[P] | null };
  const obj2: Nullable<Video> = {
    title: 'hi',
    author: null,
  };

  type Proxy<T> = {
    get(): T;
    set(value: T): void;
  };

  type Proxify<T> = {
    [P in keyof T]: Proxy<T[P]>;
  };
}

3-3 . Conditional type


//arg 의 형에 따른 type 할당도 가능함 ! 
type Check<T> = T extends string ? boolean : number;
type Type = Check<string>; // => boolean

type TypeName<T> = T extends string
  ? 'string'
  : T extends number
  ? 'number'
  : T extends boolean
  ? 'boolean'
  : T extends undefined
  ? 'undefined'
  : T extends Function
  ? 'function'
  : 'object';

type T0 = TypeName<string>;
('string');
type T1 = TypeName<'a'>;
('string');
type T2 = TypeName<() => void>;
('function');

3-4. Read only

{
  type ToDo = {
    title: string;
    description: string;
  };

  function display(todo: Readonly<ToDo>) {
    // todo.title = 'jaja'; 
    //obj는 가변할 수 있기 때문에 굉장히 위험함, 이럴때 read only 를 사용한다. 
  }
}

3-5. Partial

{
  type ToDo = {
    title: string;
    description: string;
    label: string;
    priority: 'high' | 'low';
  };

  // Partial 은 TODO 의 Key 중 일부만 가져오는 것 
  function updateTodo(todo: ToDo, fieldsToUpdate: Partial<ToDo>): ToDo {
    //기존 타입은 유지하면서 업데이트만 시킴.  
    return { ...todo, ...fieldsToUpdate };
  }
  const todo: ToDo = {
    title: 'learn TypeScript',
    description: 'study hard',
    label: 'study',
    priority: 'high',
  };
  const updated = updateTodo(todo, { priority: 'low' });
  console.log(updated);
}

3-6. Pick type

{
  type Video = {
    id: string;
    title: string;
    url: string;
    data: string;
  };
  
  //기존의 타입에서 내가 원하는 key 만 뽑아서 쓰기 
  type VideoMetadata = Pick<Video, 'id' | 'title'>;

  function getVideo(id: string): Video {
    return {
      id,
      title: 'video',
      url: 'https://..',
      data: 'byte-data..',
    };
  }
  function getVideoMetadata(id: string): VideoMetadata {
    return {
      id: id,
      title: 'title',
    };
  }
}

3-7. Omit type (<-> Pick type)

{
  type Video = {
    id: string;
    title: string;
    url: string;
    data: string;
  };

  type VideoMetadata = Omit<Video, 'url' | 'data'>;

  function getVideo(id: string): Video {
    return {
      id,
      title: 'video',
      url: 'https://..',
      data: 'byte-data..',
    };
  }
  function getVideoMetadata(id: string): VideoMetadata {
    return {
      id: id,
      title: 'title',
    };
  }
}

3-8. Record

type PageInfo = {
  title: string;
};
type Page = 'home' | 'about' | 'contact';
//key 와 그 Key 에 해당하는 value의 Type을 묶어주는 것  

const nav: Record<Page, PageInfo> = {
  home: { title: 'Home' },
  about: { title: 'About' },
  contact: { title: 'Contact' },
};

type Product = 'cat' | 'dog';
type NewProduct = Capitalize<Product>; // 'Cat' | 'Dog'

좋은 웹페이지 즐겨찾기