diff --git a/test/types/type-provider.test-d.ts b/test/types/type-provider.test-d.ts index e492c31cce..d98ea6c0ea 100644 --- a/test/types/type-provider.test-d.ts +++ b/test/types/type-provider.test-d.ts @@ -231,6 +231,40 @@ expectAssignable(server.withTypeProvider().get( } )) +// ------------------------------------------------------------------- +// TypeBox Reply Type (Different Content-types) +// ------------------------------------------------------------------- + +expectAssignable(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: Type.String() + }, + 'application/json': { + schema: Type.Object({ + msg: Type.String() + }) + } + } + }, + 500: Type.Object({ + error: Type.String() + }) + } + } + }, + async (_, res) => { + res.send('hello') + res.send({ msg: 'hello' }) + res.send({ error: 'error' }) + } +)) + // ------------------------------------------------------------------- // TypeBox Reply Type: Non Assignable // ------------------------------------------------------------------- @@ -253,6 +287,38 @@ expectError(server.withTypeProvider().get( } )) +// ------------------------------------------------------------------- +// TypeBox Reply Type: Non Assignable (Different Content-types) +// ------------------------------------------------------------------- + +expectError(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: Type.String() + }, + 'application/json': { + schema: Type.Object({ + msg: Type.String() + }) + } + } + }, + 500: Type.Object({ + error: Type.String() + }) + } + } + }, + async (_, res) => { + res.send(false) + } +)) + // ------------------------------------------------------------------- // TypeBox Reply Return Type // ------------------------------------------------------------------- @@ -280,6 +346,43 @@ expectAssignable(server.withTypeProvider().get( } )) +// ------------------------------------------------------------------- +// TypeBox Reply Return Type (Different Content-types) +// ------------------------------------------------------------------- + +expectAssignable(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: Type.String() + }, + 'application/json': { + schema: Type.Object({ + msg: Type.String() + }) + } + } + }, + 500: Type.Object({ + error: Type.String() + }) + } + } + }, + async (_, res) => { + const option = 1 as 1 | 2 | 3 + switch (option) { + case 1: return 'hello' + case 2: return { msg: 'hello' } + case 3: return { error: 'error' } + } + } +)) + // ------------------------------------------------------------------- // TypeBox Reply Return Type: Non Assignable // ------------------------------------------------------------------- @@ -302,6 +405,38 @@ expectError(server.withTypeProvider().get( } )) +// ------------------------------------------------------------------- +// TypeBox Reply Return Type: Non Assignable (Different Content-types) +// ------------------------------------------------------------------- + +expectError(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: Type.String() + }, + 'application/json': { + schema: Type.Object({ + msg: Type.String() + }) + } + } + }, + 500: Type.Object({ + error: Type.String() + }) + } + } + }, + async (_, res) => { + return false + } +)) + // ------------------------------------------------------------------- // JsonSchemaToTs Reply Type // ------------------------------------------------------------------- @@ -324,6 +459,36 @@ expectAssignable(server.withTypeProvider().get( } )) +// ------------------------------------------------------------------- +// JsonSchemaToTs Reply Type (Different Content-types) +// ------------------------------------------------------------------- + +expectAssignable(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: { type: 'string' } + }, + 'application/json': { + schema: { type: 'object', properties: { msg: { type: 'string' } } } + } + } + }, + 500: { type: 'object', properties: { error: { type: 'string' } } } + } as const + } + }, + (_, res) => { + res.send('hello') + res.send({ msg: 'hello' }) + res.send({ error: 'error' }) + } +)) + // ------------------------------------------------------------------- // JsonSchemaToTs Reply Type: Non Assignable // ------------------------------------------------------------------- @@ -344,6 +509,34 @@ expectError(server.withTypeProvider().get( } )) +// ------------------------------------------------------------------- +// JsonSchemaToTs Reply Type: Non Assignable (Different Content-types) +// ------------------------------------------------------------------- + +expectError(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: { type: 'string' } + }, + 'application/json': { + schema: { type: 'object', properties: { msg: { type: 'string' } } } + } + } + }, + 500: { type: 'object', properties: { error: { type: 'string' } } } + } as const + } + }, + async (_, res) => { + res.send(false) + } +)) + // ------------------------------------------------------------------- // JsonSchemaToTs Reply Type Return // ------------------------------------------------------------------- @@ -368,6 +561,40 @@ expectAssignable(server.withTypeProvider().get( } } )) + +// ------------------------------------------------------------------- +// JsonSchemaToTs Reply Type Return (Different Content-types) +// ------------------------------------------------------------------- + +expectAssignable(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: { type: 'string' } + }, + 'application/json': { + schema: { type: 'object', properties: { msg: { type: 'string' } } } + } + } + }, + 500: { type: 'object', properties: { error: { type: 'string' } } } + } as const + } + }, + async (_, res) => { + const option = 1 as 1 | 2 | 3 + switch (option) { + case 1: return 'hello' + case 2: return { msg: 'hello' } + case 3: return { error: 'error' } + } + } +)) + // ------------------------------------------------------------------- // JsonSchemaToTs Reply Type Return: Non Assignable // ------------------------------------------------------------------- @@ -399,6 +626,34 @@ expectError(server.withTypeProvider().get('/', { return { foo: 555 } })) +// ------------------------------------------------------------------- +// JsonSchemaToTs Reply Type Return: Non Assignable (Different Content-types) +// ------------------------------------------------------------------- + +expectError(server.withTypeProvider().get( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: { type: 'string' } + }, + 'application/json': { + schema: { type: 'object', properties: { msg: { type: 'string' } } } + } + } + }, + 500: { type: 'object', properties: { error: { type: 'string' } } } + } as const + } + }, + async (_, res) => { + return false + } +)) + // ------------------------------------------------------------------- // Reply Type Override // ------------------------------------------------------------------- @@ -419,6 +674,34 @@ expectAssignable(server.withTypeProvider().get<{Reply: b } )) +// ------------------------------------------------------------------- +// Reply Type Override (Different Content-types) +// ------------------------------------------------------------------- + +expectAssignable(server.withTypeProvider().get<{Reply: boolean}>( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: { type: 'string' } + }, + 'application/json': { + schema: { type: 'object', properties: { msg: { type: 'string' } } } + } + } + }, + 500: { type: 'object', properties: { error: { type: 'string' } } } + } as const + } + }, + async (_, res) => { + res.send(true) + } +)) + // ------------------------------------------------------------------- // Reply Type Return Override // ------------------------------------------------------------------- @@ -439,6 +722,34 @@ expectAssignable(server.withTypeProvider().get<{Reply: b } )) +// ------------------------------------------------------------------- +// Reply Type Return Override (Different Content-types) +// ------------------------------------------------------------------- + +expectAssignable(server.withTypeProvider().get<{Reply: boolean}>( + '/', + { + schema: { + response: { + 200: { + content: { + 'text/string': { + schema: { type: 'string' } + }, + 'application/json': { + schema: { type: 'object', properties: { msg: { type: 'string' } } } + } + } + }, + 500: { type: 'object', properties: { error: { type: 'string' } } } + } as const + } + }, + async (_, res) => { + return true + } +)) + // ------------------------------------------------------------------- // FastifyPlugin: Auxiliary // ------------------------------------------------------------------- diff --git a/types/type-provider.d.ts b/types/type-provider.d.ts index 9f1c8da6dc..0af41899d3 100644 --- a/types/type-provider.d.ts +++ b/types/type-provider.d.ts @@ -60,10 +60,12 @@ export interface ResolveFastifyRequestType = { - [K in keyof SchemaCompiler['response']]: CallTypeProvider -} extends infer Result ? Result[keyof Result] : unknown + [K1 in keyof SchemaCompiler['response']]: SchemaCompiler['response'][K1] extends { content: { [keyof: string]: { schema: unknown } } } ? ({ + [K2 in keyof SchemaCompiler['response'][K1]['content']]: CallTypeProvider + } extends infer Result ? Result[keyof Result] : unknown) : CallTypeProvider +} extends infer Result ? Result[keyof Result] : unknown; // The target reply type. This type is inferenced on fastify 'replies' via generic argument assignment export type FastifyReplyType = Reply