tRPCttRPC
Powered by
FluXF
tRPC•15mo ago•
1 reply
FluX

Infer TRoot and TProcedure for specific procedures (polymorphism)

Hello!
I'm trying to build a custom hook that returns specific procedures of a router:

"use client"

import { MutationLike, QueryLike } from "@trpc/react-query/shared"
import { AnyProcedure, AnyRootTypes } from "@trpc/server/unstable-core-do-not-import"
import { trpc } from "@/trpc/client"

type RequiredProcedures<TRoot extends AnyRootTypes, TProcedure extends AnyProcedure> = {
    create: MutationLike<TRoot, TProcedure>
    edit: MutationLike<TRoot, TProcedure>
    list: QueryLike<TRoot, TProcedure>
    details: QueryLike<TRoot, TProcedure>
}

export function useApi<T extends RequiredProcedures<any, any>>(
    getRouter: (
        router: typeof trpc
    ) => T extends RequiredProcedures<infer TRoot, infer TProcedure> ? RequiredProcedures<TRoot, TProcedure> : never
) {
    const router = getRouter(trpc)

    return {
        create: router.create,
        edit: router.edit,
        list: router.list,
        details: router.details,
    }
}

function Component() {
    const { create, edit } = useApi((router) => router.admin.product)

    const mut = create.useMutation()

    async function handleCreate() {
        await mut.mutateAsync({})
    }
}
"use client"

import { MutationLike, QueryLike } from "@trpc/react-query/shared"
import { AnyProcedure, AnyRootTypes } from "@trpc/server/unstable-core-do-not-import"
import { trpc } from "@/trpc/client"

type RequiredProcedures<TRoot extends AnyRootTypes, TProcedure extends AnyProcedure> = {
    create: MutationLike<TRoot, TProcedure>
    edit: MutationLike<TRoot, TProcedure>
    list: QueryLike<TRoot, TProcedure>
    details: QueryLike<TRoot, TProcedure>
}

export function useApi<T extends RequiredProcedures<any, any>>(
    getRouter: (
        router: typeof trpc
    ) => T extends RequiredProcedures<infer TRoot, infer TProcedure> ? RequiredProcedures<TRoot, TProcedure> : never
) {
    const router = getRouter(trpc)

    return {
        create: router.create,
        edit: router.edit,
        list: router.list,
        details: router.details,
    }
}

function Component() {
    const { create, edit } = useApi((router) => router.admin.product)

    const mut = create.useMutation()

    async function handleCreate() {
        await mut.mutateAsync({})
    }
}


How can I infer TRoot and TProcedure? Currently it is typed as
any
any
in
T extends RequiredProcedures<any, any>
T extends RequiredProcedures<any, any>
. But of course now my input and output types are also
any
any
, which I don't want.

Any help is appreciated! :) Thanks!
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources
Recent Announcements

Similar Threads

Was this page helpful?

Similar Threads

Infer the type of ctx for a specific procedure
iDarkLightningIiDarkLightning / ❓-help
4y ago
Typed wrappers for procedures
hagabakaHhagabaka / ❓-help
3y ago
Private procedures and serverside calls
SwifteyeSSwifteye / ❓-help
3y ago