Replies: 2 comments 2 replies
-
|
Hi @tpetry! I'm Dosu and I’m helping the orpc team. You can explicitly type your procedure handler to localize type errors by leveraging the core ProcedureHandler interface from orpc. While there isn’t a built-in utility like InferContractProcedureHandler, you can construct the type using the contract’s generics. Here’s how you can do it: import { ProcedureHandler } from "@orpc/server";
import {
InferContractRouterInputs,
InferContractRouterOutputs,
InferContractRouterErrorMap,
InferContractRouterMeta,
} from "@orpc/contract";
// For a contract with a procedure key "xyz"
type XyzInput = InferContractRouterInputs<typeof contract>["xyz"];
type XyzOutput = InferContractRouterOutputs<typeof contract>["xyz"];
type XyzErrorMap = InferContractRouterErrorMap<typeof contract>["xyz"];
type XyzMeta = InferContractRouterMeta<typeof contract>["xyz"];
type XyzContext = /* your context type here */;
// The handler type:
type XyzProcedure = ProcedureHandler<
XyzContext,
XyzInput,
XyzOutput,
XyzErrorMap,
XyzMeta
>;You can now use export const xyzHandler: XyzProcedure = implement(contract)
.xyz
.handler(async ({ input }) => {
// ...
});This approach ensures that type errors are caught in the handler file, not just at the router level, making debugging much easier. This pattern is recommended in the orpc codebase and discussions for managing type complexity and error localization in large routers [source] [source]. If you want to make this more ergonomic, you could define a utility type: type InferContractProcedureHandler<
TContract,
TKey extends keyof TContract["procedures"],
TContext
> = ProcedureHandler<
TContext,
InferContractRouterInputs<TContract>[TKey],
InferContractRouterOutputs<TContract>[TKey],
InferContractRouterErrorMap<TContract>[TKey],
InferContractRouterMeta<TContract>[TKey]
>;Then use: type XyzProcedure = InferContractProcedureHandler<typeof contract, "xyz", XyzContext>;This keeps your handler types DRY and localizes errors for each procedure. To reply, just mention @dosu. How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other |
Beta Was this translation helpful? Give feedback.
-
|
This pattern currently is not supported. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
In cases when you are dynamically constructing the router from procedure handler from many different files, it would be great to infer the type of a procedure. I don't know if its possible - but its at least not documented.
Sure, you can omit the type as typescript will infer it and yell at you when you make a mistake. But then you get a very complicated type error at the router which is implementing dozens of of procedures and its hard to see which one is the problem - and why. By typing the
xyzHandlerdirectly, the error is local to theprocedures/xyz.tsfile.Beta Was this translation helpful? Give feedback.
All reactions