Skip to content

Commit 9dfcee8

Browse files
authored
fix(contract, server): has no properties in common with type ts-problem (#247)
In previous attempt: https://github.com/unnoq/orpc/pull/244 we forgot cover some cases <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Updated type definitions for configuration and middleware interfaces to enhance type safety. - Standardized context handling across core modules to ensure consistent use of the initial context. - Resolved underlying compatibility issues, improving overall stability without impacting runtime functionality. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 5737a7d commit 9dfcee8

File tree

6 files changed

+21
-21
lines changed

6 files changed

+21
-21
lines changed

packages/contract/src/builder.test-d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('ContractBuilder', () => {
2525
type MetaDef = { meta1?: string, meta2?: number }
2626

2727
expectTypeOf(builder.$meta<MetaDef>({ meta1: 'value' })).toEqualTypeOf<
28-
ContractBuilder<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, MetaDef>
28+
ContractBuilder<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, MetaDef & Record<never, never>>
2929
>()
3030

3131
// @ts-expect-error - invalid initial meta

packages/contract/src/builder.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ export class ContractBuilder<
3636
*/
3737
$meta<U extends Meta>(
3838
initialMeta: U,
39-
): ContractBuilder<TInputSchema, TOutputSchema, TErrorMap, U> {
39+
): ContractBuilder<TInputSchema, TOutputSchema, TErrorMap, U & Record<never, never>> {
40+
/**
41+
* We need `& Record<never, never>` to deal with `has no properties in common with type` error
42+
*/
43+
4044
return new ContractBuilder({
4145
...this['~orpc'],
4246
meta: initialMeta,

packages/server/src/builder.test-d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ describe('Builder', () => {
157157
expectTypeOf(
158158
builder.middleware(({ context, next, path, procedure, errors, signal }, input, output) => {
159159
expectTypeOf(input).toEqualTypeOf<unknown>()
160-
expectTypeOf(context).toEqualTypeOf<CurrentContext>()
160+
expectTypeOf(context).toEqualTypeOf<InitialContext>()
161161
expectTypeOf(path).toEqualTypeOf<readonly string[]>()
162162
expectTypeOf(procedure).toEqualTypeOf<
163163
Procedure<Context, Context, AnySchema, AnySchema, ErrorMap, BaseMeta>
@@ -173,7 +173,7 @@ describe('Builder', () => {
173173
})
174174
}),
175175
).toEqualTypeOf<
176-
DecoratedMiddleware<CurrentContext, { extra: boolean }, unknown, any, ORPCErrorConstructorMap<any>, BaseMeta>
176+
DecoratedMiddleware<InitialContext, { extra: boolean }, unknown, any, ORPCErrorConstructorMap<any>, BaseMeta>
177177
>()
178178

179179
// @ts-expect-error --- conflict context
@@ -184,7 +184,7 @@ describe('Builder', () => {
184184
expectTypeOf(
185185
builder.middleware(({ next }, input: 'input', output: MiddlewareOutputFn<'output'>) => next()),
186186
).toEqualTypeOf<
187-
DecoratedMiddleware<CurrentContext, Record<never, never>, 'input', 'output', ORPCErrorConstructorMap<any>, BaseMeta>
187+
DecoratedMiddleware<InitialContext, Record<never, never>, 'input', 'output', ORPCErrorConstructorMap<any>, BaseMeta>
188188
>()
189189
})
190190
})

packages/server/src/builder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ export class Builder<
118118
}
119119

120120
middleware<UOutContext extends Context, TInput, TOutput = any>( // = any here is important to make middleware can be used in any output by default
121-
middleware: Middleware<TCurrentContext, UOutContext, TInput, TOutput, ORPCErrorConstructorMap<TErrorMap>, TMeta>,
122-
): DecoratedMiddleware<TCurrentContext, UOutContext, TInput, TOutput, ORPCErrorConstructorMap<any>, TMeta> { // ORPCErrorConstructorMap<any> ensures middleware can used in any procedure
121+
middleware: Middleware<TInitialContext, UOutContext, TInput, TOutput, ORPCErrorConstructorMap<TErrorMap>, TMeta>,
122+
): DecoratedMiddleware<TInitialContext, UOutContext, TInput, TOutput, ORPCErrorConstructorMap<any>, TMeta> { // ORPCErrorConstructorMap<any> ensures middleware can used in any procedure
123123
return decorateMiddleware(middleware)
124124
}
125125

packages/server/src/implementer.test-d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('Implementer', () => {
4141
it('works', () => {
4242
const mid = implementer.nested.middleware(({ context, next, path, procedure, errors, signal }, input, output) => {
4343
expectTypeOf(input).toEqualTypeOf<unknown>()
44-
expectTypeOf(context).toEqualTypeOf<CurrentContext>()
44+
expectTypeOf(context).toEqualTypeOf<InitialContext>()
4545
expectTypeOf(path).toEqualTypeOf<readonly string[]>()
4646
expectTypeOf(procedure).toEqualTypeOf<
4747
Procedure<Context, Context, AnySchema, AnySchema, ErrorMap, BaseMeta | Meta>
@@ -57,9 +57,9 @@ describe('Implementer', () => {
5757
})
5858
})
5959

60-
expectTypeOf(mid).toMatchTypeOf<
60+
expectTypeOf(mid).toEqualTypeOf<
6161
DecoratedMiddleware<
62-
CurrentContext,
62+
InitialContext,
6363
{ extra: boolean },
6464
unknown,
6565
any,
@@ -77,7 +77,7 @@ describe('Implementer', () => {
7777
implementer.middleware(({ next }, input: 'input', output: MiddlewareOutputFn<'output'>) => next()),
7878
).toEqualTypeOf<
7979
DecoratedMiddleware<
80-
CurrentContext,
80+
InitialContext,
8181
Record<never, never>,
8282
'input',
8383
'output',

packages/server/src/implementer.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ export interface RouterImplementer<
2323
> {
2424
middleware<UOutContext extends Context, TInput, TOutput = any>( // = any here is important to make middleware can be used in any output by default
2525
middleware: Middleware<
26-
TCurrentContext,
26+
TInitialContext,
2727
UOutContext,
2828
TInput,
2929
TOutput,
3030
ORPCErrorConstructorMap<InferContractRouterErrorMap<T>>,
3131
InferContractRouterMeta<T>
3232
>,
33-
): DecoratedMiddleware<TCurrentContext, UOutContext, TInput, TOutput, ORPCErrorConstructorMap<any>, InferContractRouterMeta<T>> // ORPCErrorConstructorMap<any> ensures middleware can used in any procedure
33+
): DecoratedMiddleware<TInitialContext, UOutContext, TInput, TOutput, ORPCErrorConstructorMap<any>, InferContractRouterMeta<T>> // ORPCErrorConstructorMap<any> ensures middleware can used in any procedure
3434

3535
use<UOutContext extends Context, UInContext extends Context = TCurrentContext>(
3636
middleware: Middleware<
@@ -169,19 +169,15 @@ export type Implementer<
169169
TCurrentContext extends Context ,
170170
> =
171171
& {
172-
$context<U extends Context>(): Implementer<TContract, U, U>
172+
$context<U extends Context>(): Implementer<TContract, U & Record<never, never>, U> // We need `& Record<never, never>` to deal with `has no properties in common with type` error
173173
$config(config: BuilderConfig): Implementer<TContract, TInitialContext, TCurrentContext>
174174
}
175175
& ImplementerInternal<TContract, TInitialContext, TCurrentContext>
176176

177-
export function implement<
178-
TContract extends AnyContractRouter,
179-
TInitialContext extends Context,
180-
TCurrentContext extends Context,
181-
>(
182-
contract: TContract,
177+
export function implement<T extends AnyContractRouter, TContext extends Context = Record<never, never>>(
178+
contract: T,
183179
config: BuilderConfig = {},
184-
): Implementer<TContract, TInitialContext, TCurrentContext> {
180+
): Implementer<T, TContext, TContext> {
185181
const implInternal = implementerInternal(contract, config, [])
186182

187183
const impl = new Proxy(implInternal, {

0 commit comments

Comments
 (0)