mirror of
https://github.com/zoriya/typebox.git
synced 2026-06-02 02:55:05 +00:00
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.32.30",
|
||||
"version": "0.32.31",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.32.30",
|
||||
"version": "0.32.31",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.13.2",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.32.30",
|
||||
"version": "0.32.31",
|
||||
"description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
|
||||
@@ -80,8 +80,9 @@ function ScoreUnion(schema: TSchema, references: TSchema[], value: any): number
|
||||
}
|
||||
}
|
||||
function SelectUnion(union: TUnion, references: TSchema[], value: any): TSchema {
|
||||
let [select, best] = [union.anyOf[0], 0]
|
||||
for (const schema of union.anyOf) {
|
||||
const schemas = union.anyOf.map((schema) => Deref(schema, references))
|
||||
let [select, best] = [schemas[0], 0]
|
||||
for (const schema of schemas) {
|
||||
const score = ScoreUnion(schema, references, value)
|
||||
if (score > best) {
|
||||
select = schema
|
||||
|
||||
@@ -30,15 +30,22 @@ import type { TSchema } from '../../type/schema/index'
|
||||
import type { TRef } from '../../type/ref/index'
|
||||
import type { TThis } from '../../type/recursive/index'
|
||||
import { TypeBoxError } from '../../type/error/index'
|
||||
import { Kind } from '../../type/symbols/index'
|
||||
|
||||
export class TypeDereferenceError extends TypeBoxError {
|
||||
constructor(public readonly schema: TRef | TThis) {
|
||||
super(`Unable to dereference schema with $id '${schema.$id}'`)
|
||||
}
|
||||
}
|
||||
/** Dereferences a schema from the references array or throws if not found */
|
||||
export function Deref(schema: TRef | TThis, references: TSchema[]): TSchema {
|
||||
const index = references.findIndex((target) => target.$id === schema.$ref)
|
||||
if (index === -1) throw new TypeDereferenceError(schema)
|
||||
return references[index]
|
||||
function Resolve(schema: TThis | TRef, references: TSchema[]): TSchema {
|
||||
const target = references.find((target) => target.$id === schema.$ref)
|
||||
if (target === undefined) throw new TypeDereferenceError(schema)
|
||||
return Deref(target, references)
|
||||
}
|
||||
/** Dereferences a schema from the references array or throws if not found */
|
||||
export function Deref(schema: TSchema, references: TSchema[]): TSchema {
|
||||
// prettier-ignore
|
||||
return (schema[Kind] === 'This' || schema[Kind] === 'Ref')
|
||||
? Resolve(schema as never, references)
|
||||
: schema
|
||||
}
|
||||
|
||||
@@ -145,4 +145,20 @@ describe('value/cast/Union', () => {
|
||||
value: 'B',
|
||||
})
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/880
|
||||
// ----------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
it('Should dereference union variants', () => {
|
||||
const A = Type.Object({ type: Type.Literal('A') }, { $id: 'A' })
|
||||
const B = Type.Object({ type: Type.Literal('B'), value: Type.Number() }, { $id: 'B' })
|
||||
const RA = Type.Union([A, B])
|
||||
const RB = Type.Union([Type.Ref(A), Type.Ref(B)])
|
||||
// variant 0
|
||||
Assert.IsEqual(Value.Cast(RA, [A, B], { type: 'B' }), { type: 'B', value: 0 })
|
||||
Assert.IsEqual(Value.Cast(RB, [A, B], { type: 'B' }), { type: 'B', value: 0 })
|
||||
// variant 1
|
||||
Assert.IsEqual(Value.Cast(RA, [A, B], { type: 'A' }), { type: 'A' })
|
||||
Assert.IsEqual(Value.Cast(RB, [A, B], { type: 'A' }), { type: 'A' })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user