type Video = {
  title: string;
  author: string;
};

*// --map 방식--*
*//  type - 1*
type Member = {
  [key: string]: string; *// object(객체)에 타입지정해야 할 속성이 너무 많으면*
};
const john: Member = { name: 'john', id: 'm-123', };

*//  type - 2*
type Optional<T> = {
  [P in keyof T]?: T[P]; *// for...in*
  *// T 타입 안의 key(P)*
};

*//  type - 3*
type ReadOnly<T> = {
  readonly [P in keyof T]: T[P];
};

*//  type - 4*
type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};
// ---------------------

*// #1*
type CheckType = Optional<Member>;

*// #2*
type VideoOptional = Optional<Video>;

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

*// #4*
const animal2: ReadOnly<Animal> = {
  name: 'cat',
  age: 10,
};
//animal2.name = 'dog';  *// error*
  
*// #5*
const obj: Nullable<Animal> = {
  name: null,
  age: null,
};
const obj2: Nullable<Animal> = {
  name: null,
  age: 20,
};

  
// others...
type Proxy<T> = {
  get(): T;
  set(value: T): void;
};
type Proxify<T> = {
  [P in keyof T]: Proxy<T[P]>;
};