FrontEnd Develop/Project : TODOMVC

Zustand X Generic 심층분석.

Frisbeen 2025. 4. 9. 17:05

Zustand create 완전 정복을 위하여..
늘 context API로 전역상태 관리를 활용하던 내가 , zustand 공식문서를 읽어보며 zustand 활용법을 공부했다.

 

zustand에는 Generic type으로 선언된 함수가 매우많아서 Generic 관련 내용 또한 매우 중요하다고 판단하여 같이 콜라보하여 공부했다.


1. 제네릭이란 무엇인가?

TypeScript에서 흔히 보이는 함수<T> 형태는 제네릭(Generic) 문법입니다.

function identity<T>(value: T): T {
  return value;
}

identity<string>('hello'); // ✉️ T = string → 매개변수도, 리턴값도 string

즉, T라는 타입은 함수 선언부에서 고정하지 않고, 호출할 때 지정할 수 있는 타입 매개변수입니다.


2. 그럼 create는?

Zustand의 create()는 제네릭 함수입니다. 원형은 다음과 같이 생겼습니다:

declare function create<T extends object>(
  initializer: (set, get, api) => T
): UseBoundStore<StoreApi<T>>;
  • T extends object : T는 반드시 객체여야 함
  • 매개변수로 set, get, api를 받는 함수 → 이 함수가 상태 정의
  • 이 내부 함수의 리턴값은 T 타입의 객체
  • 최종적으로 create() UseBoundStore<StoreApi<T>> 타입의 함수를 리턴

즉, create는 **고차 함수 (Higher-order function)**입니다.

입력: 상태 정의 함수

출력: 상태를 제어할 수 있는 커스텀 훅 함수 (() => T)


3. 제네릭에서 extends의 쓰임

 

  1. 인터페이스 간 상속과 확장
interface Animal { name: string }
interface Dog extends Animal { breed: string }

//Dog가 그럼 속성 두개다 가져야할까요 필수로? 퀴즈임 ㅋㅋ

 

2. 객체 리터럴 제한

function foo<T extends { name: string }>(val: T) {}
  • T는 최소한 { name: string } 구조를 가져야 함
  • T = { name: string; age: number } 이런 것도 OK

이처럼 T extends object는 "T는 객체여야만 해!" 라는 제약입니다.

 

3. type alias 에 extend

function foo<T extends object>(param: T) {}

T는 객체이기만 하면 돼 + 어떤 속성있는진 알빠 아님.

**“나는 단지 이게 원시값(string, number, boolean)이 아니었으면 좋겠어. 객체면 뭐든 돼.”**

4. 그럼 우리는 지금 뭘 한 것인가?

const useAuthStore = create<AuthState>((set) => ({
  user: null,
  isAuthLoading: true,
  setUser: (user) => set({ user }),
  setAuthLoading: (loading) => set({ isAuthLoading: loading }),
}));

여기서 우리가 한 일:

  • zustand의 제네릭 함수 create<T extends object>
  • 우리가 만든 타입 alias AuthState
  • T 자리에 명시적으로 넣어 준 것 → create<AuthState>
  • 그 내부 함수의 리턴타입은 T 타입 객체이다.
  • 외부함수의 리턴타입은 그 내부 함수를 조작하는 함수 (커스텀훅)이다.

5. UseBoundStore<StoreApi>는 함수인가요?

네. 함수입니다.
이건 () => StoreApi<T> 형태의 함수 타입이고, 우리가 흔히 쓰는 훅입니다.

const { user } = useAuthStore(); // → 이게 함수 실행

이 훅을 실행하면 zustand가 관리하는 상태 객체 (T)를 제어할 수 있는 API가 반환됩니다.


6. 핵심 요약

  • create<T>는 제네릭 함수이고, 내부에서 T extends object 제약이 있음
  • 우리는 T = AuthState로 넣었고, 이 타입은 객체 타입이므로 조건을 만족함
  • 이 create 함수는 () => T 타입의 객체를 조작하는 커스텀 훅 함수를 반환함
  • 그 커스텀훅의 리턴타입은 T 타입의 객체이다.
  • 그 훅을 실행해서 상태를 읽거나, set 함수로 상태를 업데이트할 수 있음

7. 한 줄 결론

create<AuthState>는 zustand가 제네릭으로 정의한 상태 생성기 함수에 우리가 만든 상태 타입(AuthState)을 주입한 것이며, 그 결과로 상태를 제어할 수 있는 커스텀 훅 함수가 리턴된다!