Revision 0.31.21 (#650)

* Extends Optional Property Check

* Additional Tests and Version
This commit is contained in:
sinclairzx81
2023-10-29 20:46:06 +09:00
committed by GitHub
parent a9cfd7e9c3
commit ce1ace5ffb
4 changed files with 98 additions and 37 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@sinclair/typebox",
"version": "0.31.20",
"version": "0.31.21",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@sinclair/typebox",
"version": "0.31.20",
"version": "0.31.21",
"license": "MIT",
"devDependencies": {
"@sinclair/hammer": "^0.18.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.31.20",
"version": "0.31.21",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
+44 -34
View File
@@ -1144,6 +1144,9 @@ export namespace TypeGuard {
function IsOptionalSchema(value: unknown): value is boolean | undefined {
return ValueGuard.IsUndefined(value) || TSchema(value)
}
// ----------------------------------------------------------------
// Types
// ----------------------------------------------------------------
/** Returns true if the given value is TAny */
export function TAny(schema: unknown): schema is TAny {
// prettier-ignore
@@ -1533,40 +1536,42 @@ export namespace TypeGuard {
}
/** Returns true if the given value is TSchema */
export function TSchema(schema: unknown): schema is TSchema {
// prettier-ignore
return (
ValueGuard.IsObject(schema) &&
(TAny(schema) ||
TArray(schema) ||
TBoolean(schema) ||
TBigInt(schema) ||
TAsyncIterator(schema) ||
TConstructor(schema) ||
TDate(schema) ||
TFunction(schema) ||
TInteger(schema) ||
TIntersect(schema) ||
TIterator(schema) ||
TLiteral(schema) ||
TNever(schema) ||
TNot(schema) ||
TNull(schema) ||
TNumber(schema) ||
TObject(schema) ||
TPromise(schema) ||
TRecord(schema) ||
TRef(schema) ||
TString(schema) ||
TSymbol(schema) ||
TTemplateLiteral(schema) ||
TThis(schema) ||
TTuple(schema) ||
TUndefined(schema) ||
TUnion(schema) ||
TUint8Array(schema) ||
TUnknown(schema) ||
TUnsafe(schema) ||
TVoid(schema) ||
(TKind(schema) && TypeRegistry.Has(schema[Kind] as any)))
ValueGuard.IsObject(schema)
) && (
TAny(schema) ||
TArray(schema) ||
TBoolean(schema) ||
TBigInt(schema) ||
TAsyncIterator(schema) ||
TConstructor(schema) ||
TDate(schema) ||
TFunction(schema) ||
TInteger(schema) ||
TIntersect(schema) ||
TIterator(schema) ||
TLiteral(schema) ||
TNever(schema) ||
TNot(schema) ||
TNull(schema) ||
TNumber(schema) ||
TObject(schema) ||
TPromise(schema) ||
TRecord(schema) ||
TRef(schema) ||
TString(schema) ||
TSymbol(schema) ||
TTemplateLiteral(schema) ||
TThis(schema) ||
TTuple(schema) ||
TUndefined(schema) ||
TUnion(schema) ||
TUint8Array(schema) ||
TUnknown(schema) ||
TUnsafe(schema) ||
TVoid(schema) ||
(TKind(schema) && TypeRegistry.Has(schema[Kind] as any))
)
}
}
@@ -1986,7 +1991,12 @@ export namespace TypeExtends {
!TypeGuard.TObject(right) ? TypeExtendsResult.False :
(() => {
for (const key of Object.getOwnPropertyNames(right.properties)) {
if (!(key in left.properties)) return TypeExtendsResult.False
if (!(key in left.properties) && !TypeGuard.TOptional(right.properties[key])) {
return TypeExtendsResult.False
}
if(TypeGuard.TOptional(right.properties[key])) {
return TypeExtendsResult.True
}
if (Property(left.properties[key], right.properties[key]) === TypeExtendsResult.False) {
return TypeExtendsResult.False
}
+51
View File
@@ -174,4 +174,55 @@ describe('type/extends/Object', () => {
const R = TypeExtends.Extends(Type.Object({ a: Type.Number() }), Type.Date())
Assert.IsEqual(R, TypeExtendsResult.False)
})
// ----------------------------------------------------------------
// Optional
// ----------------------------------------------------------------
it('Should extend optional 1', () => {
const A = Type.Object({ a: Type.Number() })
const B = Type.Object({ a: Type.Optional(Type.Number()) })
const C = TypeExtends.Extends(A, B)
Assert.IsEqual(C, TypeExtendsResult.True)
})
it('Should extend optional 2', () => {
const A = Type.Object({ a: Type.Number() })
const B = Type.Object({ a: Type.Optional(Type.Number()) })
const C = TypeExtends.Extends(B, A)
Assert.IsEqual(C, TypeExtendsResult.False)
})
it('Should extend optional 3', () => {
const A = Type.Object({
x: Type.Optional(Type.Number()),
y: Type.Number(),
})
const B = Type.Object({
y: Type.Number(),
z: Type.Number(),
})
const R = TypeExtends.Extends(A, B)
Assert.IsEqual(R, TypeExtendsResult.False)
})
it('Should extend optional 4', () => {
const A = Type.Object({
x: Type.Number(),
y: Type.Number(),
})
const B = Type.Object({
y: Type.Number(),
z: Type.Number(),
})
const R = TypeExtends.Extends(A, B)
Assert.IsEqual(R, TypeExtendsResult.False)
})
it('Should extend optional 5', () => {
const A = Type.Object({
x: Type.Number(),
y: Type.Number(),
})
const B = Type.Object({
y: Type.Number(),
z: Type.Optional(Type.Number()),
})
const R = TypeExtends.Extends(A, B)
Assert.IsEqual(R, TypeExtendsResult.True)
})
})