Skip to content

Commit c6a7e5f

Browse files
committed
feat(types): use exact input types (don't allow not defined properties)
1 parent a6d923e commit c6a7e5f

File tree

1 file changed

+53
-33
lines changed

1 file changed

+53
-33
lines changed

src/types.ts

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,31 @@ type TRPCSubscriptionObserver<TValue, TError> = {
3333
onComplete: () => void
3434
}
3535

36-
type Resolver<TRouter extends AnyTRPCRouter, TProcedure extends AnyTRPCProcedure> = (
37-
input: inferProcedureInput<TProcedure>,
38-
opts?: ProcedureOptions,
39-
) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>
40-
41-
type SubscriptionResolver<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = (
42-
input: inferProcedureInput<TProcedure>,
43-
opts: ProcedureOptions &
44-
Partial<
45-
TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>
46-
>,
47-
) => Unsubscribable
36+
export type Exact<Shape, T extends Shape> = {
37+
[Key in keyof T]: Key extends keyof Shape
38+
? T[Key] extends Date
39+
? T[Key]
40+
: T[Key] extends object
41+
? Exact<Shape[Key], T[Key]>
42+
: T[Key]
43+
: never
44+
}
4845

4946
export type DecorateProcedure<
5047
TProcedure extends AnyTRPCProcedure,
5148
TRouter extends AnyTRPCRouter,
5249
> = TProcedure extends AnyTRPCQueryProcedure
5350
? {
5451
useQuery: <
55-
TQueryFnData = inferTransformedProcedureOutput<TRouter, TProcedure>,
56-
TError = TRPCClientErrorLike<TRouter>,
57-
TData = TQueryFnData,
58-
TQueryData = TQueryFnData,
59-
TQueryKey extends QueryKey = QueryKey,
52+
TQueryFnData extends inferTransformedProcedureOutput<TRouter, TProcedure>,
53+
TError extends TRPCClientErrorLike<TRouter>,
54+
TData extends TQueryFnData,
55+
TQueryData extends TQueryFnData,
56+
TQueryKey extends QueryKey,
57+
TInput extends inferProcedureInput<TProcedure>,
58+
TTInput extends TInput,
6059
>(
61-
input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>,
60+
input: MaybeRefOrGetter<Exact<TInput, TTInput>>,
6261
opts?: MaybeRefOrGetter<
6362
Omit<
6463
UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>,
@@ -69,23 +68,32 @@ export type DecorateProcedure<
6968
}
7069
>,
7170
) => UseQueryReturnType<TData, TError>
72-
query: Resolver<TRouter, TProcedure>
73-
invalidate: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => Promise<void>
74-
setQueryData: (
71+
query: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
72+
input: Exact<TInput, TTInput>,
73+
opts?: ProcedureOptions,
74+
) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>
75+
invalidate: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
76+
input?: MaybeRefOrGetter<Exact<TInput, TTInput>>,
77+
) => Promise<void>
78+
setQueryData: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
7579
updater: inferTransformedProcedureOutput<TRouter, TProcedure>,
76-
input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>,
80+
input?: MaybeRefOrGetter<Exact<TInput, TTInput>>,
7781
) => ReturnType<QueryClient['setQueryData']>
78-
key: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => QueryKey
82+
key: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
83+
input?: MaybeRefOrGetter<Exact<TInput, TTInput>>,
84+
) => QueryKey
7985
} & (TProcedure['_def']['$types']['input'] extends { cursor?: infer CursorType }
8086
? {
8187
useInfiniteQuery: <
82-
TQueryFnData = inferTransformedProcedureOutput<TRouter, TProcedure>,
83-
TError = TRPCClientErrorLike<TRouter>,
84-
TData = InfiniteData<TQueryFnData>,
85-
TQueryData = TQueryFnData,
86-
TQueryKey extends QueryKey = QueryKey,
88+
TQueryFnData extends inferTransformedProcedureOutput<TRouter, TProcedure>,
89+
TError extends TRPCClientErrorLike<TRouter>,
90+
TData extends InfiniteData<TQueryFnData>,
91+
TQueryData extends TQueryFnData,
92+
TQueryKey extends QueryKey,
93+
TInput extends Omit<inferProcedureInput<TProcedure>, 'cursor'>,
94+
TTInput extends TInput,
8795
>(
88-
input: MaybeRefOrGetter<Omit<inferProcedureInput<TProcedure>, 'cursor'>>,
96+
input: MaybeRefOrGetter<Exact<TInput, TTInput>>,
8997
opts?: MaybeRefOrGetter<
9098
Omit<
9199
UnwrapRef<
@@ -104,7 +112,10 @@ export type DecorateProcedure<
104112
: object)
105113
: TProcedure extends AnyTRPCMutationProcedure
106114
? {
107-
mutate: Resolver<TRouter, TProcedure>
115+
mutate: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
116+
input: Exact<TInput, TTInput>,
117+
opts?: ProcedureOptions,
118+
) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>
108119
useMutation: <
109120
TData = inferTransformedProcedureOutput<TRouter, TProcedure>,
110121
TError = TRPCClientErrorLike<TRouter>,
@@ -120,9 +131,18 @@ export type DecorateProcedure<
120131
}
121132
: TProcedure extends AnyTRPCSubscriptionProcedure
122133
? {
123-
subscribe: SubscriptionResolver<TProcedure, TRouter>
124-
useSubscription: (
125-
input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>,
134+
subscribe: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
135+
input: Exact<TInput, TTInput>,
136+
opts: ProcedureOptions &
137+
Partial<
138+
TRPCSubscriptionObserver<
139+
inferProcedureOutput<TProcedure>,
140+
TRPCClientErrorLike<TRouter>
141+
>
142+
>,
143+
) => Unsubscribable
144+
useSubscription: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(
145+
input: MaybeRefOrGetter<Exact<TInput, TTInput>>,
126146
opts: ProcedureOptions &
127147
Partial<
128148
TRPCSubscriptionObserver<

0 commit comments

Comments
 (0)