타입스크립트 교과서 7장 정리

이수빈·2023년 12월 12일
0

Typescript

목록 보기
8/17
post-thumbnail

useState 타입분석

  • 오버로딩은 매개변수의 유무로 구분됨 => 매개변수가 있으면 첫번째 오버로딩, 없으면 두번째 오버로딩에 해당함.

  • 파라미터가 없으면 undefined와 S가 모두 적용될 수 있도록 union 타입을 설정해줌, 초기 파라미터가 있다면 S타입을 제네릭을 통해 공유함.

    function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
    
    function useState<S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>];
  • Dispatch, SetStateAction

  • setStateAction type이 S이거나, S type을 파라미터로 받아서 S로 반환하는 콜백함수이기 때문에,

  • setCount(1) 이나 setCount((prev) => prev+1)의 형태가 가능한 것임.

 type SetStateAction<S> = S | ((prevState: S) => S);
    // this technically does accept a second argument, but it's already under a deprecation warning
    // and it's not even released so probably better to not define it.
    type Dispatch<A> = (value: A) => void;
    // Since action _can_ be undefined, dispatch may be called without any parameters.
  • 두번째의 경우 파라미터 기본값이 없을때 => 제너릭으로 type을 표기해야함.

  • 단 value는 string or undefined이므로, undefined일 경우를 처리해줘야함.

  • lazy init 가능하게 할 수 있음.(초기값을 가공해야할때) => state의 매개변수로 함수를 return 하는 형태

  • useEffect안에서 가공해주는 거랑 무슨 차이가 있을까?

const [value, setValue] = useState<String>(); 

const [word, setword] = useState(() => { return 복잡한 함수()});

useEffect 타입분석

  • useEffect는 EffectCallback을 인자값으로 받는다. => return 값은 void

  • return 값은 void이거나 Destructor이다

  • Destructor는 callback함수인데, return값이 없는 cleanup 함수이다.

  • useEffect의 EffectCallback은 async 키워드와 같이 사용할 수 없다.

  • async함수는 항상 promise를 반환하기 때문에 void나 Destructor를 반환하는 EffectCallback 함수와 호환되지 않는다.

  function useEffect(effect: EffectCallback, deps?: DependencyList): void;

  type DependencyList = ReadonlyArray<unknown>;

    // NOTE: callbacks are _only_ allowed to return either void, or a destructor.
    type EffectCallback = () => (void | Destructor);


	type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };
  • [UNDEFINED_VOID_ONLY]: never 가 있는 이유? => History 확인 => View git blame!!

  • 타입스크립트 브랜딩을 사용하기 위해 해당 type을 return 값으로 넣어줌.

  • TS에서 원시값을 구분하기 위해 사용된다.

ref) https://velog.io/@sjyoung428/Typescript-%EB%B8%8C%EB%9E%9C%EB%94%A9

  • 유로를 달러로 바꿔주는 함수일때 => number형태의 모든 값을 받을 수 있음. eur 단위의 파라미터만 받아야 하는데
type Brand<K, T> = K & { __brand: T };

type EUR = Brand<number, "EUR">;
type USD = Brand<number, "USD">;
type KRW = Brand<number, "KRW">;

let eur = 10 as EUR;
let usd = 10 as USD;
let krw = 1000 as KRW;

const euroToUsd = (euro: EUR): USD => {
  return (euro * 0.99) as USD;
};

console.log(euroToUsd(usd));
console.log(euroToUsd(krw));
console.log(euroToUsd(eur));
eur = 1000 as EUR;
console.log(euroToUsd(eur));
  • 그래서 해당 type에 원시값을 구분하기위해 brand라는 속성을 새로 만들어주는 기법임.

  • brand 속성을 만들어준 후 as를 통해 명시적으로 타입을 변환함. => eur type만 함수에 넣을 수 있다.

  • Readonly Array => 한번 array가 생성되면 length를 수정할 수 없다.


interface ReadonlyArray<T> {
    /**
     * Gets the length of the array. This is a number one higher than the highest element defined in an array.
     */
    readonly length: number;
    ...
    
    }

useCallback, useMemo 타입분석

  • useMemo에 첫번째 매개변수인 factory가 함수를 반환한다면 useCallback으로 대체 할 수 있다.

function useCallback<T extends Function>(callback: T, deps: DependencyList): T;

function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T;

useRef 타입분석

  • 3개의 오버로딩 존재 => MutableRefObject와 RefObject의 차이는?

  • MutableRefObject => 컴포넌트에서 값을 저장할때의 type임. (리렌더링 x)

  • RefObject => 참조값을 갖고있는 객체임 => 제너릭으로 Dom 요소값을 넣어줘야함. + null 값도 넣어줘야 RefObject로 인식함.

  • 타입이 다를때 두번째 오버로딩으로 들어간다.

    function useRef<T>(initialValue: T): MutableRefObject<T>;
    function useRef<T>(initialValue: T | null): RefObject<T>;
    function useRef<T = undefined>(): MutableRefObject<T | undefined>;

MutableRefObject vs RejObject

  • MutableRefObject는 current 속성을 수정 할 수 있지만, RejObject는 current 속성을 수정 할 수 없다.

  • MutableObject가 좀 더 넓은 타입이다.

    interface MutableRefObject<T> {
        current: T;
    }
    
      interface RefObject<T> {
        readonly current: T | null;
    }


const inputEl = useRef<HTMLHeadElement>(document.querySelector("head")) // 이런식으로도 사용가능
profile
응애 나 애기 개발자

0개의 댓글