Additional Fast Path Undefined Checks (#439)

This commit is contained in:
sinclairzx81
2023-05-17 12:08:41 +09:00
committed by GitHub
parent f740515feb
commit 41dae20a28
5 changed files with 40 additions and 5 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@sinclair/typebox",
"version": "0.28.10",
"version": "0.28.11",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@sinclair/typebox",
"version": "0.28.10",
"version": "0.28.11",
"license": "MIT",
"devDependencies": {
"@sinclair/hammer": "^0.17.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.28.10",
"version": "0.28.11",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",

View File

@@ -1353,6 +1353,14 @@ export namespace TypeGuard {
export namespace ExtendsUndefined {
export function Check(schema: TSchema): boolean {
if (schema[Kind] === 'Undefined') return true
if (schema[Kind] === 'Not') {
const not = schema as TNot
return Check(not.allOf[1])
}
if (schema[Kind] === 'Intersect') {
const intersect = schema as TIntersect
return intersect.allOf.every((schema) => Check(schema))
}
if (schema[Kind] === 'Union') {
const union = schema as TUnion
return union.anyOf.some((schema) => Check(schema))

View File

@@ -238,8 +238,8 @@ export namespace ValueCheck {
if (!Visit(property, references, value[knownKey])) {
return false
}
if (Types.ExtendsUndefined.Check(property)) {
return knownKey in value
if (Types.ExtendsUndefined.Check(property) && !(knownKey in value)) {
return false
}
} else {
if (IsExactOptionalProperty(value, knownKey) && !Visit(property, references, value[knownKey])) {

View File

@@ -2,6 +2,33 @@ import { Type } from '@sinclair/typebox'
import { Ok, Fail } from './validate'
describe('type/compiler/Object', () => {
// -----------------------------------------------------
// TypeCompiler Only
// -----------------------------------------------------
it('Should handle extends undefined check 1', () => {
const T = Type.Object({
A: Type.Not(Type.Number(), Type.Undefined()),
B: Type.Union([Type.Number(), Type.Undefined()]),
C: Type.Intersect([Type.Undefined(), Type.Undefined()]),
})
Ok(T, {
A: undefined,
B: undefined,
C: undefined,
})
})
// https://github.com/sinclairzx81/typebox/issues/437
it('Should handle extends undefined check 2', () => {
const T = Type.Object({
A: Type.Not(Type.Null(), Type.Undefined()),
})
Ok(T, { A: undefined })
Fail(T, { A: null })
Fail(T, {})
})
// -----------------------------------------------------
// Standard Checks
// -----------------------------------------------------
it('Should not validate a number', () => {
const T = Type.Object({})
Fail(T, 42)