lukeautry / tsoa

Build OpenAPI-compliant REST APIs using TypeScript and Node
MIT License
3.48k stars 498 forks source link

The array [0] gets validated as the floating point number 0 #1635

Closed alexanderisacson closed 1 month ago

alexanderisacson commented 4 months ago

Sorting

Expected Behavior

It should not validate to a zero.

I have created a test controller which has two endpoints that should work the same way.

export class TestController {
 @Post("numberFirst")
  numberFirst(@Body() body: { [key: string]: number | number[] }) {
    return body;
  }
  @Post("arrayFirst")
  arrayFirst(@Body() body: { [key: string]: number[] | number }) {
    return body;
  }
  @Post("recordArrayFirst")
  recordArrayFirst(@Body() body: Record<string, number[] | number>) {
    return body;
  }
  @Post("recordNumberFirst")
  recordNumberFirst(@Body() body: Record<string, number | number[]>) {
    return body;
  }
}

The difference is the order of the union in the body type.

Current Behavior

If I send this body: { "array": [ 0 ], "number": 0 } to each of the following functions I get the following results:

numberFirst: { "array": 0, "number": 0 } arrayFirst: { "array": [ 0 ], "number": [ 0 ] } recordArrayFirst: { "array": [ 0 ], "number": [ 0 ] } recordNumberFirst: { "message": "Validation Failed", "details": { "body": { "message": "\"array,number\" is an excess property and therefore is not allowed", "value": { "number": 0, "array": [ 0 ] } } } }

Context (Environment)

Version of the library: "tsoa": "^6.0.1" Version of NodeJS: v20.11.1

github-actions[bot] commented 4 months ago

Hello there alexanderisacson 👋

Thank you for opening your very first issue in this project.

We will try to get back to you as soon as we can.👀

github-actions[bot] commented 3 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

alexanderisacson commented 3 months ago

Still a problem

WoH commented 3 months ago

You can disable these coercions via config. Otherwise we will always try to coerce left to right

alexanderisacson commented 2 months ago

@WoH thanks for your reply. Not sure that I fully understand it though 😄 .

I assume that this the configuration parameter you are referring to: https://tsoa-community.github.io/reference/interfaces/_tsoa_runtime.RoutesConfig.html#bodyCoercion

I tried to find out what bodyCoercion actually does but it's not completely clear. If set to true (which is the default) it will convert the strings "true"/"false" to a boolean (regardless of case). I will also treat undefined and null as false if it's a boolean. Furthermore it will require the input to be of the correct

How tsoa treats arrays, and why an array is accepted as a number and a number is an array, if coercion is turned on, was not clear to me. And I don't understand why the last call does not validate at all....

But setting turning off bodyCoercion does return the body I expected in my use case. Namely leaving the array as an array and the number as a number.

github-actions[bot] commented 1 month ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days