-
-
Notifications
You must be signed in to change notification settings - Fork 37
Description
Hi,
first of all I want to say thank you for this great library!
I use it to share typed api routes between backend and frontend.
Basically I define a contract using json schemas. This is then used for the validation and for the types on the backend and for creating the queries for the frontend.
Unfortunately upgrading to 2.12.0 or 3.0.0 breaks my code.
I heavily simplified the example below to show the issue. Some types seem to be not needed but this is due to the simplification.
If I define the schema externally for initContract then this works with the newer versions as well.
But my inline schema for the params property only works with version 2.9.2.
Any idea what causes this behaviour?
I would like to continue using inline schema definitions.
Simplified example
import type { FromSchema, JSONSchema } from 'json-schema-to-ts'
// Simplified version
type ContractRoute = {
params: JSONSchema
query: JSONSchema
}
type Contract = {
[key: string]: ContractRoute
}
type ProcessContract<T extends Contract> = {
[K in keyof T]: T[K]
}
const initContract = <TRouter extends Contract>(routes: ProcessContract<TRouter>): TRouter => routes
type ContractRouteImplementation<T extends ContractRoute> = () => {
handler: (request: { Params: FromSchema<T['params']>; Query: FromSchema<T['query']> }) => void
}
type ServerObj<T extends Contract> = {
[TKey in keyof T]: ContractRouteImplementation<T[TKey]>
}
type InitialisedServer<T extends Contract> = {
contract: T
routes: ServerObj<T>
}
const initServer = <T extends Contract>(contract: T, routes: ServerObj<T>): InitialisedServer<T> => ({
contract,
routes,
})
// Example
const externSchema = {
type: 'object',
properties: {
str: { type: 'string' },
},
required: ['str'],
additionalProperties: false,
} as const
const contract = initContract({
demo: {
params: {
type: 'object',
properties: {
str: { type: 'string' },
},
required: ['str'],
additionalProperties: false,
} as const,
query: externSchema,
},
})
initServer(contract, {
demo: () => ({
handler: async (request) => {},
}),
})
