Przejdź do treści
Pobierz wartość po typowanej głębokiej ścieżce

    ↑↓ ruch · ⏎ otwórz · esc zamknij

    Wzorce

    Jak odczytać `user.address.city` przez ścieżkę wielokrotnego użytku bez utraty typu wyniku?

    Wygeneruj rekurencyjnie poprawne krotki kluczy, a potem zużywaj po jednym kluczu, by obliczyć wartość na końcu.

    Przepis

    type Paths<T> = T extends object
      ? { [K in keyof T]-?: [K] | [K, ...Paths<T[K]>] }[keyof T]
      : []
    
    type PathValue<T, P extends readonly PropertyKey[]> =
      P extends readonly [infer K, ...infer Rest]
        ? K extends keyof T
          ? Rest extends readonly PropertyKey[]
            ? PathValue<T[K], Rest>
            : never
          : never
        : T
    
    function getPath<T, const P extends readonly PropertyKey[]>(
      value: T,
      ...path: P & Paths<T>
    ): PathValue<T, P> {
      let current: unknown = value
      for (const key of path) {
        current = (current as Record<PropertyKey, unknown>)[key]
      }
      return current as PathValue<T, P>
    }
    
    type Model = {
      user: { address: { city: string }; active: boolean }
    }
    
    declare const model: Model
    const city = getPath(model, 'user', 'address', 'city')

    Build to kompiluje i sprawdza każdy wynik poniżej.

    Jak to działa

    1. 01
      type Paths<T> = T extends object

      Typ mapowany emituje po jednej krotce dla każdej osiągalnej ścieżki właściwości.

    2. 02
      PathValue<T[K], Rest>

      Resolver podąża za pierwszym kluczem i rekurencyjnie przechodzi resztę krotki.

    Co dostajesz

    Gdzie to zawodzi

    Bardzo głębokie schematy mogą trafić na limit rekurencji kompilatora, a tablice ujawniają więcej kluczy, niż zwykle chce API ścieżek. Dla dużych modeli dodaj limit głębokości lub osobną obsługę tablic.

    Wniosek

    Przedstaw ścieżkę jako krotkę, gdy każdy segment zmienia typ następnego.

    Zobacz też

    Wzorce