Closed jordi-petit closed 2 months ago
@jordi-petit Hi,
TypeBox schematics are based on the Json Schema specification. The patternProperties
keyword is a formal keyword in that specification, but not necessarily in OpenAPI (which historically has been at odds with the Json Schema specification). I believe this has improved in OpenAPI 3.1 which suggests support for Json Schema Draft 2020-12.
Information on patternProperties
can be found at the following link.
https://json-schema.org/understanding-json-schema/reference/object#patternProperties
Could you please clarify how to express the concept of dictionary (or associative array) with TypeBox in a way that is interoperable with other tools?
It is possible to construct custom schematics using the Unsafe type. This type provides an escape hatch and allows you to specify arbitrary schematics with custom inference.
import { Type, Static } from '@sinclair/typebox'
type TUser = Static<typeof TUser>
const TUser = Type.Object({
name: Type.String(),
email: Type.String(),
})
type TUserDict = Static<typeof TUserDict>
const TUserDict = Type.Unsafe<Record<string, TUser>>({
type: 'object',
additionalProperties: TUser
})
TypeBox has partial validation support for Records created in this way, but does require a slightly different definition.
import { Type, Static } from '@sinclair/typebox'
import { Value } from '@sinclair/typebox/value'
type TUser = Static<typeof TUser>
const TUser = Type.Object({
name: Type.String(),
email: Type.String(),
})
type TUserDict = Static<typeof TUserDict>
const TUserDict = Type.Unsafe<Record<string, TUser>>(Type.Object({}, {
additionalProperties: TUser
}))
// works only with the above definition of TUserDict
const R = Value.Check(TUserDict, {
user1: { name: 'user1', email: 'user1@domain.com' },
user2: { name: 'user2', email: 'user2@domain.com' }
})
console.log(R) // true
Hope this helps S
Thanks for your help, the distinction between openapi and its different versions and json schema is important, indeed.
I would like to define a type that represents a dictionary of, say, users indexed by their keys (strings). The
Record
type looks like the proper candidate and, indeed, does the job:However, the resulting schema is the following:
where the use of
patternProperties
seems odd, because:https://swagger.io/docs/specification/data-models/dictionaries/ explains how to write dictionary schemas and uses
additionalProperties
rather thanpatternProperties
.interactive API documentation from OpenAPI such as Swagger or Scalar fail to interpret these
patternProperties
, and https://swagger.io/docs/specification/data-models/keywords/ reports it as an "unsupported keyword".client generators such as Hey Api end-up understanding that the resulting type is a map of strings to
unknow
(rather than to an explicit type).Could you please clarify how to express the concept of dictionary (or associative array) with TypeBox in a way that is interoperable with other tools?
PS. I have seen there was a Dict type that is now deprecated.
Thanks for your work!