sinclairzx81 / typebox

Json Schema Type Builder with Static Type Resolution for TypeScript
Other
4.85k stars 155 forks source link

Should coerce type to array #823

Closed woody146 closed 5 months ago

woody146 commented 6 months ago

Current

Value.Convert(Type.Object({
    a: Type.Array(Type.String()),
  }), {a: 'string'} )
=> {a: 'string'}

Should be (like ajv with coerceTypes: 'array')

Value.Convert(Type.Object({
    a: Type.Array(Type.String()),
  }), {a: string'} )
=> {a: ['string']}

In api with get method, client sends field a with array type but only one element such as /api/?a=string After converting, server receives {a: 'string'}, but it should be {a: ['string']}

sinclairzx81 commented 6 months ago

@woody146 Hi, thanks for the suggestion.

Let me have a think about this. The current convert logic was based on the idea that primitive types (string, number and boolean) should be coerce-able in some form or another, but structural types (array and object) should not as invariance between structural types and primitives types may be lost (although this is more of a guiding principal hoping to simplify the rules of conversion)...the coerceTypes: 'array' was considered however.

I think in the case of /api/?a=string, one would naturally express this as { a: string } (and where expressing it as { a: string[] } would only obfuscate the receiving type / value (this is largely framework dependent concerns outside of TypeBox). But can you think of any other cases were you would want coerceTypes: 'array' ?

I'll leave this issue open for further discussion Cheers! S

sinclairzx81 commented 5 months ago

@woody146 Hiya!

Good news, Have gone ahead and implemented array coercion as a default (the implementation and impact of which wasn't too bad and the performance should be alright). You can use this functionality on 0.32.21.

// 0.32.12
const R = Value.Convert(Type.Object({ // const R = { a: [ 'string' ] }
  a: Type.Array(Type.String()),
}), { a: 'string' })

I'll close up this issue for now Thanks for the suggestion! S