tsoa
tsoa copied to clipboard
Record<string, unknown> does not allow additional properties
Sorting
-
I'm submitting a ...
- [x] bug report
- [ ] feature request
- [ ] support request
-
I confirm that I
- [x] used the search to make sure that a similar issue hasn't already been submit
Expected Behavior
A body with a field attributes: Record<string, unknown> and should allow additional properties even with "noImplicitAdditionalProperties": "throw-on-extras", in tsoa.json.
Current Behavior
A body with a field attributes: Record<string, unknown> with "noImplicitAdditionalProperties": "throw-on-extras", in tsoa.json triggers a validation error:
{"requestBody.attributes":{"message":"\"test\" is an excess property and therefore is not allowed","value":{"test":"test"}}}
Possible Solution
Steps to Reproduce
- Add an interface
interface GeometryPostBody { attributes?: Record<string | number, unknown> } - Set the interface as the expected body of a POST request
- Try to POST with the body
{"attributes": {"test": "test"}} - Receive a validation error
{"requestBody.attributes":{"message":"\"test\" is an excess property and therefore is not allowed","value":{"test":"test"}}}
Context (Environment)
Version of the library: 3.14.1 Version of NodeJS: v16.13.1
- Confirm you were using yarn not npm: [ ]
Detailed Description
Breaking change?
Hello there yannbriancon 👋
Thank you for opening your very first issue in this project.
We will try to get back to you as soon as we can.👀
Hello all!
If it can help, I found a workaround by replacing Record<string, unknown> by { [key: string]: unknown }.
It would still be great to find how to fix the real issue with Record 😉
The swagger.json is very different in each case:
- With
Record<string, unknown>:
...
"Record_string.unknown_": {
"properties": {},
"type": "object",
"description": "Construct a type with a set of properties K of type T"
},
"Dto": {
"properties": {
"attributes": {
"allOf": [
{
"$ref": "#/components/schemas/Record_string.unknown_"
}
]
}
},
"type": "object",
}
...
- With
{ [key: string]: unknown }:
...
"Dto": {
"properties": {
"attributes": {
"properties": {},
"additionalProperties": {},
"type": "object"
}
},
"type": "object",
}
...
I also ran into this issue. I was hoping to do something like
type Foo = string;
Record<Foo, number>
But not only does this not work, { [key: Foo]: number} doesn't work either and instead fails with Error: Only string indexers are supported. This is unfortunate since I was hoping to split Foo as a separate type so that I can proper give it decorators.
@SebastienGllmt I've had the same problem as you. I want to accept a body of type Record<UUID, {data: string, signature: string}> where type UUID = string.
@yannbriancon's { [key: string]: unknown } trick works for this and I think it will work for you too. I can choose the type to be {[key: string]: {data: string, signature: string}} for TSOA. This type even is compatible with Record<UUID, {data: string, signature: string}> that I then can use in the rest of my application without casting.
I have a related question based on the above. According the Swagger definition for "Free-form object": https://swagger.io/docs/specification/data-models/data-types/#object, the following specifications are equivalent representations:
type: object
type: object
additionalProperties: true
type: object
additionalProperties: {}
However, using the type { [key: string]: unknown } becomes:
type: object
properties: {}
additionalProperties: {}
The additional properties field is messing with an auto-generated API documentation tool that I'm using. Does anyone know how to remove this properties field using tsoa? I can always do it manually, but was hoping to be able to generate the Swagger and feed it into the documentation tool automatically. Thanks!