유틸리티 타입
import type { StoreOf, StateOf, RawStateOf, DepsOf, DetectConflicts } from '@hurum/core'Store 정의에서 타입을 추출하기 위한 타입 유틸리티예요. 타입을 중복 정의하지 않고 Store 타입을 참조해야 하는 함수, 훅, 테스트를 작성할 때 유용해요.
StoreOf<T>
섹션 제목: “StoreOf<T>”Store 정의에서 Store 인스턴스 타입을 추출해요.
type StoreOf<T> = T extends StoreDefinition<infer D, infer R, infer C, infer I> ? StoreInstance<D, R, C, I> : neverconst CartStore = Store({ state: { items: [] as CartItem[] } }) .computed({ total: (s) => s.items.reduce((sum, i) => sum + i.price, 0) }) .intents(CartIntents) .executors(AddItemExec)
// Extract the instance typetype CartInstance = StoreOf<typeof CartStore>
function processCart(store: CartInstance) { const state = store.getState() // ^? { items: CartItem[], total: number }}StateOf<T>
섹션 제목: “StateOf<T>”Store 정의에서 결합된 상태 타입 (raw + Computed)을 추출해요. store.getState()가 반환하는 타입이에요.
type StateOf<T> = T extends StoreDefinition<unknown, infer R, infer C> ? ResolvedState<R> & C : nevertype CartState = StateOf<typeof CartStore>// { items: CartItem[], total: number }
function renderTotal(state: CartState) { return `$${state.total.toFixed(2)}`}RawStateOf<T>
섹션 제목: “RawStateOf<T>”Store 정의에서 raw 상태 타입만 추출해요 (Computed 필드 제외). on 핸들러가 반환해야 하는 형태예요.
type RawStateOf<T> = T extends StoreDefinition<unknown, infer R, unknown> ? R : nevertype CartRawState = RawStateOf<typeof CartStore>// { items: CartItem[] }// Note: `total` is NOT included (it's computed)DepsOf<T>
섹션 제목: “DepsOf<T>”Store 정의에서 의존성 타입을 추출해요.
type DepsOf<T> = T extends StoreDefinition<infer D, unknown, unknown> ? D : neverconst CartStore = Store({ state: { items: [] as CartItem[] } }) .deps<{ repo: CartRepo; analytics: Analytics }>()
type CartDeps = DepsOf<typeof CartStore>// { repo: CartRepo; analytics: Analytics }
function createTestDeps(): CartDeps { return { repo: new MockCartRepo(), analytics: new MockAnalytics(), }}DetectConflicts<A, B>
섹션 제목: “DetectConflicts<A, B>”두 의존성 타입 간 충돌하는 키를 감지해요. A와 B 모두에 동일한 키가 다른 타입으로 존재하면, 충돌하는 키 이름의 유니언으로 나타나요.
type DetectConflicts<A, B> = { [K in keyof A & keyof B]: A[K] extends B[K] ? B[K] extends A[K] ? never : K : K}[keyof A & keyof B]type ParentDeps = { api: RestApi; logger: Logger }type ChildDeps = { api: GraphQLApi; cache: Cache }
type Conflicts = DetectConflicts<ParentDeps, ChildDeps>// 'api' -- because RestApi !== GraphQLApi
// Use this to catch mismatches early:type AssertNoConflicts = [Conflicts] extends [never] ? true : false// ^? false -- there IS a conflict참고사항
섹션 제목: “참고사항”- 이 타입들은 Store 정의 (빌더)에서 작동해요. Store 인스턴스가 아닌
typeof MyStore를 전달하세요. StateOf는 해석된 Nested 상태를 포함해요.Nested(ChildStore)필드는 자식의 전체 상태 (raw + Computed)로 해석돼요.- 모든 유틸리티 타입은 입력이 유효한
StoreDefinition이 아니면never를 반환해요.