Publish
This commit is contained in:
147
test/runtime/type/clone/clone.ts
Normal file
147
test/runtime/type/clone/clone.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
// --------------------------------------------------------------------
|
||||
// $id deletion was omitted from 0.26.0 to reduce complexity overhead.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// import { Type } from '@sinclair/typebox'
|
||||
// import { Assert } from '../../assert'
|
||||
|
||||
// describe('type/Clone', () => {
|
||||
// it('Should retain source type $id for cloned objects', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Object({ x: S, y: S })
|
||||
// Assert.equal(T.properties.x.$id, undefined)
|
||||
// Assert.equal(T.properties.y.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should retain source type $id when composing objects with cloned arrays', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Function([S], S)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Array', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Array(S)
|
||||
// Assert.equal(T.items.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Composite', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Composite([Type.Object({ a: S }), Type.Object({ b: S })])
|
||||
// Assert.equal(T.properties.a.$id, undefined)
|
||||
// Assert.equal(T.properties.b.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Constructor', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Constructor([S], S)
|
||||
// Assert.equal(T.parameters[0].$id, undefined)
|
||||
// Assert.equal(T.returns.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Function', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Function([S], S)
|
||||
// Assert.equal(T.parameters[0].$id, undefined)
|
||||
// Assert.equal(T.returns.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Intersect', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Intersect([S, S])
|
||||
// Assert.equal(T.allOf[0].$id, undefined)
|
||||
// Assert.equal(T.allOf[1].$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Intersect with unevaluatedProperties', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Intersect([S, S], { unevaluatedProperties: S })
|
||||
// // @ts-ignore
|
||||
// Assert.equal(T.unevaluatedProperties.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Not', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Not(S, S)
|
||||
// Assert.equal(T.allOf[0].not.$id, undefined)
|
||||
// Assert.equal(T.allOf[1].$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Object', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Object({ x: S, y: S })
|
||||
// Assert.equal(T.properties.x.$id, undefined)
|
||||
// Assert.equal(T.properties.y.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for nested Object', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const N = Type.Object({ s: S }, { $id: 'N' })
|
||||
// const T = Type.Object({ x: S, y: S, z: N })
|
||||
// Assert.equal(T.properties.x.$id, undefined)
|
||||
// Assert.equal(T.properties.y.$id, undefined)
|
||||
// Assert.equal(T.properties.z.$id, undefined)
|
||||
// Assert.equal(T.properties.z.properties.s.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Object additionalProperties', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Object({}, { additionalProperties: S })
|
||||
// // @ts-ignore
|
||||
// Assert.equal(T.additionalProperties!.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Promise', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Promise(S)
|
||||
// Assert.equal(T.item.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Record', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Record(Type.String(), S)
|
||||
// Assert.equal(T.patternProperties['^.*$'].$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Tuple', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Tuple([S, S])
|
||||
// Assert.equal(T.items![0]!.$id, undefined)
|
||||
// Assert.equal(T.items![1]!.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should remove cloned $id for Union', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Union([S, S])
|
||||
// Assert.equal(T.anyOf[0]!.$id, undefined)
|
||||
// Assert.equal(T.anyOf[1]!.$id, undefined)
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should retain cloned $id for wrapped Recursive 1', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Object({
|
||||
// x: Type.Recursive(
|
||||
// (Self) =>
|
||||
// Type.Object({
|
||||
// self: Type.Optional(Self),
|
||||
// }),
|
||||
// { $id: 'RecursiveClone' },
|
||||
// ),
|
||||
// })
|
||||
// Assert.equal(T.properties.x.$id, 'RecursiveClone')
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// it('Should retain cloned $id for wrapped Recursive 2', () => {
|
||||
// const S = Type.String({ $id: 'S' })
|
||||
// const T = Type.Tuple([
|
||||
// Type.Recursive(
|
||||
// (Self) =>
|
||||
// Type.Object({
|
||||
// self: Type.Optional(Self),
|
||||
// }),
|
||||
// { $id: 'RecursiveClone' },
|
||||
// ),
|
||||
// ])
|
||||
// Assert.equal(T.items![0].$id, 'RecursiveClone')
|
||||
// Assert.equal(S.$id, 'S')
|
||||
// })
|
||||
// })
|
||||
1
test/runtime/type/clone/index.ts
Normal file
1
test/runtime/type/clone/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
import './clone'
|
||||
95
test/runtime/type/extends/any.ts
Normal file
95
test/runtime/type/extends/any.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Any', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = any extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = any extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = any extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = any extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = any extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = any extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = any extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = any extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = any extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = any extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = any extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = any extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = any extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = any extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = any extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = any extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = any extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = any extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
})
|
||||
264
test/runtime/type/extends/array.ts
Normal file
264
test/runtime/type/extends/array.ts
Normal file
@@ -0,0 +1,264 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Array', () => {
|
||||
// ----------------------------------------------
|
||||
// Generic Varying
|
||||
// ----------------------------------------------
|
||||
it('Should extend Array Varying 1', () => {
|
||||
type T = Array<any> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array Varying 2', () => {
|
||||
type T = Array<string> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array Varying 3', () => {
|
||||
type T = Array<any> extends Array<string> ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array Varying 4', () => {
|
||||
type T = Array<number> extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Number()), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// ----------------------------------------------
|
||||
// Any
|
||||
// ----------------------------------------------
|
||||
it('Should extend Any', () => {
|
||||
type T = Array<any> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = Array<any> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = Array<any> extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = Array<any> extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = Array<any> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = Array<any> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = Array<any> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = Array<string> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array 3', () => {
|
||||
type T = Array<any> extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = Array<any> extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = Array<any> extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = Array<any> extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = Array<any> extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 4', () => {
|
||||
type T = Array<any> extends { length: '1' } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({ length: Type.Literal('1') }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 5', () => {
|
||||
type T = Array<any> extends { length: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({ length: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = Array<any> extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = Array<any> extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = Array<any> extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = Array<string> extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 5', () => {
|
||||
type T = Array<any> extends any | Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Any(), Type.Array(Type.String())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = Array<any> extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = Array<any> extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.Any()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// ----------------------------------------------
|
||||
// Constrained
|
||||
// ----------------------------------------------
|
||||
it('Should extend constrained Any', () => {
|
||||
type T = Array<string> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Unknown', () => {
|
||||
type T = Array<string> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained String', () => {
|
||||
type T = Array<string> extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Boolean', () => {
|
||||
type T = Array<string> extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Number', () => {
|
||||
type T = Array<string> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Integer', () => {
|
||||
type T = Array<string> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Array 1', () => {
|
||||
type T = Array<string> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Array 2', () => {
|
||||
type T = Array<string> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Array 3', () => {
|
||||
type T = Array<string> extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Tuple', () => {
|
||||
type T = Array<string> extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Object 1', () => {
|
||||
type T = Array<string> extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Object 2', () => {
|
||||
type T = Array<string> extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Object 3', () => {
|
||||
type T = Array<string> extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Object 4', () => {
|
||||
type T = Array<string> extends { length: '1' } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({ length: Type.Literal('1') }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Object 5', () => {
|
||||
type T = Array<string> extends { length: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({ length: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Union 1', () => {
|
||||
type T = Array<string> extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Null(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Union 2', () => {
|
||||
type T = Array<string> extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Union 3', () => {
|
||||
type T = Array<string> extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Union 4', () => {
|
||||
type T = Array<string> extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Union 5', () => {
|
||||
type T = Array<string> extends any | Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.String())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Null', () => {
|
||||
type T = Array<string> extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Undefined', () => {
|
||||
type T = Array<string> extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Void', () => {
|
||||
type T = Array<string> extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = Array<string> extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Array(Type.String()), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
71
test/runtime/type/extends/async-iterator.ts
Normal file
71
test/runtime/type/extends/async-iterator.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/AsyncIterator', () => {
|
||||
// ----------------------------------------------
|
||||
// Generic Varying
|
||||
// ----------------------------------------------
|
||||
it('Should extend AsyncIterator 1', () => {
|
||||
type T = AsyncIterableIterator<any> extends AsyncIterableIterator<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.Any()), Type.AsyncIterator(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend AsyncIterator 2', () => {
|
||||
type T = AsyncIterableIterator<string> extends AsyncIterableIterator<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.String()), Type.AsyncIterator(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend AsyncIterator 3', () => {
|
||||
type T = AsyncIterableIterator<'hello'> extends AsyncIterableIterator<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.Literal('hello')), Type.AsyncIterator(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend AsyncIterator 4', () => {
|
||||
type T = AsyncIterableIterator<string> extends AsyncIterableIterator<'hello'> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.String()), Type.AsyncIterator(Type.Literal('hello')))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend AsyncIterator 5', () => {
|
||||
type T = AsyncIterableIterator<string> extends AsyncIterableIterator<'hello' | number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.String()), Type.AsyncIterator(Type.Union([Type.Literal('hello'), Type.Number()])))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend AsyncIterator 6', () => {
|
||||
type T = AsyncIterableIterator<'hello' | number> extends AsyncIterableIterator<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.Union([Type.Literal('hello'), Type.Number()])), Type.AsyncIterator(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// --------------------------------------------------------------------
|
||||
// Structural
|
||||
// --------------------------------------------------------------------
|
||||
it('Should extends Any 1', () => {
|
||||
type T = AsyncIterableIterator<number> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extends Any 2', () => {
|
||||
type T = any extends AsyncIterableIterator<number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.AsyncIterator(Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extends Unknown 1', () => {
|
||||
type T = AsyncIterableIterator<number> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.Number()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extends Unknown 2', () => {
|
||||
type T = unknown extends AsyncIterableIterator<number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.AsyncIterator(Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extends Never 1', () => {
|
||||
type T = AsyncIterableIterator<number> extends never ? 1 : 2
|
||||
const R = ExtendsCheck(Type.AsyncIterator(Type.Number()), Type.Never())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extends Never 2', () => {
|
||||
type T = never extends AsyncIterableIterator<number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Never(), Type.AsyncIterator(Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
})
|
||||
100
test/runtime/type/extends/bigint.ts
Normal file
100
test/runtime/type/extends/bigint.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/BigInt', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = bigint extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = bigint extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = bigint extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = bigint extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = bigint extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = bigint extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = bigint extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = bigint extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = bigint extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = bigint extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = bigint extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Object({ a: Type.Literal(10) }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = bigint extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = bigint extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = bigint extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = bigint extends boolean | bigint ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Boolean(), Type.BigInt()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = bigint extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = bigint extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = bigint extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = bigint extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.BigInt(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
90
test/runtime/type/extends/boolean.ts
Normal file
90
test/runtime/type/extends/boolean.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Boolean', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = boolean extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = boolean extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = boolean extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = boolean extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = boolean extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = boolean extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = boolean extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = boolean extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = boolean extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = boolean extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = boolean extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = boolean extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = boolean extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = boolean extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = boolean extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = boolean extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = boolean extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Boolean(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
210
test/runtime/type/extends/constructor.ts
Normal file
210
test/runtime/type/extends/constructor.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Constructor', () => {
|
||||
it('Should extend Function', () => {
|
||||
type T = (new () => number) extends () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Function([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Constructor 1', () => {
|
||||
type T = (new () => number) extends new () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Constructor([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 2', () => {
|
||||
type T = (new () => any) extends new () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Any()), Type.Constructor([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 3', () => {
|
||||
type T = (new () => number) extends new () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Any()), Type.Constructor([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 4', () => {
|
||||
type T = (new (a: number) => number) extends new () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Number()], Type.Number()), Type.Constructor([], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Constructor 5', () => {
|
||||
type T = (new (a: number | string) => number) extends new (a: number) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Union([Type.Number(), Type.String()])], Type.Number()), Type.Constructor([Type.Number()], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 6', () => {
|
||||
type T = (new (a: number) => number) extends new (a: number | string) => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Number()], Type.Number()), Type.Constructor([Type.Union([Type.Number(), Type.String()])], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Constructor 7', () => {
|
||||
type T = (new (a: number, b: number) => number) extends new (a: number) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Number(), Type.Number()], Type.Number()), Type.Constructor([Type.Number()], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Constructor 8', () => {
|
||||
type T = (new (a: number) => number) extends new (a: number, b: number) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Number()], Type.Number()), Type.Constructor([Type.Number(), Type.Number()], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 9', () => {
|
||||
type T = (new () => number) extends new () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Constructor([], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 9', () => {
|
||||
type T = (new () => any) extends new () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Any()), Type.Constructor([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 10', () => {
|
||||
type T = (new () => Array<any>) extends new () => object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Array(Type.Any())), Type.Constructor([], Type.Object({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 11', () => {
|
||||
type T = (new () => Array<string>) extends new () => object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Array(Type.String())), Type.Constructor([], Type.Object({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 12', () => {
|
||||
type T = (new () => object) extends new () => Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Object({})), Type.Constructor([], Type.Array(Type.Any())))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Constructor 13', () => {
|
||||
type T = (new (a: unknown) => number) extends new (a: any) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Unknown()], Type.Number({})), Type.Constructor([Type.Any()], Type.Number({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 14', () => {
|
||||
type T = (new (a: any) => number) extends new (a: unknown) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([Type.Any()], Type.Number({})), Type.Constructor([Type.Unknown()], Type.Number({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 15', () => {
|
||||
type T = (new () => any) extends new () => unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Any({})), Type.Constructor([], Type.Unknown({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Constructor 16', () => {
|
||||
type T = (new () => unknown) extends new () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Unknown({})), Type.Constructor([], Type.Any({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Any', () => {
|
||||
type T = (new () => number) extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = (new () => number) extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = (new () => number) extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = (new () => number) extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = (new () => number) extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = (new () => number) extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = (new () => number) extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 3', () => {
|
||||
type T = (new () => number) extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = (new () => number) extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = (() => number) extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = (new () => number) extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = (new () => number) extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = (new () => number) extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 4', () => {
|
||||
type T = (new () => number) extends { length: '1' } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({ length: Type.Literal('1') }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = (new () => number) extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Null(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = (new () => number) extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = (new () => number) extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = (new () => number) extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 5', () => {
|
||||
type T = (new () => number) extends any | Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.String())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = (new () => number) extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = (new () => number) extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = (new () => number) extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = (new () => number) extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
95
test/runtime/type/extends/date.ts
Normal file
95
test/runtime/type/extends/date.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Date', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = Date extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = Date extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = Date extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = Date extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = Date extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = Date extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = Date extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = Date extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = Date extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = Date extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = Date extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = Date extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = Date extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = Date extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = Date extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = Date extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = Date extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = Date extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Date(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
})
|
||||
210
test/runtime/type/extends/function.ts
Normal file
210
test/runtime/type/extends/function.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Function', () => {
|
||||
it('Should extend Constructor 1', () => {
|
||||
type T = (() => number) extends new () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Constructor([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Function 1', () => {
|
||||
type T = (() => number) extends () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Function([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 2', () => {
|
||||
type T = (() => any) extends () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Any()), Type.Function([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 3', () => {
|
||||
type T = (() => number) extends () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Any()), Type.Function([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 4', () => {
|
||||
type T = ((a: number) => number) extends () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Number()], Type.Number()), Type.Function([], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Function 5', () => {
|
||||
type T = ((a: number | string) => number) extends (a: number) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Union([Type.Number(), Type.String()])], Type.Number()), Type.Function([Type.Number()], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 6', () => {
|
||||
type T = ((a: number) => number) extends (a: number | string) => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Number()], Type.Number()), Type.Function([Type.Union([Type.Number(), Type.String()])], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Function 7', () => {
|
||||
type T = ((a: number, b: number) => number) extends (a: number) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Number(), Type.Number()], Type.Number()), Type.Function([Type.Number()], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Function 8', () => {
|
||||
type T = ((a: number) => number) extends (a: number, b: number) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Number()], Type.Number()), Type.Function([Type.Number(), Type.Number()], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 9', () => {
|
||||
type T = (() => number) extends () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Function([], Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 9', () => {
|
||||
type T = (() => any) extends () => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Any()), Type.Function([], Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 10', () => {
|
||||
type T = (() => Array<any>) extends () => object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Array(Type.Any())), Type.Function([], Type.Object({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 11', () => {
|
||||
type T = (() => Array<string>) extends () => object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Array(Type.String())), Type.Function([], Type.Object({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 12', () => {
|
||||
type T = (() => object) extends () => Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Object({})), Type.Function([], Type.Array(Type.Any())))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Function 13', () => {
|
||||
type T = ((a: unknown) => number) extends (a: any) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Unknown()], Type.Number({})), Type.Function([Type.Any()], Type.Number({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 14', () => {
|
||||
type T = ((a: any) => number) extends (a: unknown) => number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([Type.Any()], Type.Number({})), Type.Function([Type.Unknown()], Type.Number({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 15', () => {
|
||||
type T = (() => any) extends () => unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Any({})), Type.Function([], Type.Unknown({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Function 16', () => {
|
||||
type T = (() => unknown) extends () => any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Unknown({})), Type.Function([], Type.Any({})))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Any', () => {
|
||||
type T = (() => number) extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = (() => number) extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = (() => number) extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = (() => number) extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = (() => number) extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = (() => number) extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = (() => number) extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 3', () => {
|
||||
type T = (() => number) extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = (() => number) extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = (() => number) extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = (() => number) extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = (() => number) extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = (() => number) extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 4', () => {
|
||||
type T = (() => number) extends { length: '1' } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({ length: Type.Literal('1') }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 5', () => {
|
||||
type T = (() => number) extends { length: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({ length: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = (() => number) extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Null(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = (() => number) extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = (() => number) extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = (() => number) extends any | Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 5', () => {
|
||||
type T = (() => number) extends any | Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.String())]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = (() => number) extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = (() => number) extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = (() => number) extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
27
test/runtime/type/extends/index.ts
Normal file
27
test/runtime/type/extends/index.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import './any'
|
||||
import './array'
|
||||
import './async-iterator'
|
||||
import './bigint'
|
||||
import './boolean'
|
||||
import './constructor'
|
||||
import './date'
|
||||
import './function'
|
||||
import './integer'
|
||||
import './iterator'
|
||||
import './literal'
|
||||
import './not'
|
||||
import './null'
|
||||
import './number'
|
||||
import './object'
|
||||
import './promise'
|
||||
import './record'
|
||||
import './regexp'
|
||||
import './string'
|
||||
import './symbol'
|
||||
import './template-literal'
|
||||
import './tuple'
|
||||
import './uint8array'
|
||||
import './undefined'
|
||||
import './union'
|
||||
import './unknown'
|
||||
import './void'
|
||||
95
test/runtime/type/extends/integer.ts
Normal file
95
test/runtime/type/extends/integer.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Integer', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = number extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = number extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = number extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = number extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = number extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = number extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = number extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = number extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = number extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = number extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = number extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Object({ a: Type.Literal(10) }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = number extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = number extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = number extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = number extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Integer(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = number extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
71
test/runtime/type/extends/iterator.ts
Normal file
71
test/runtime/type/extends/iterator.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Iterator', () => {
|
||||
// ----------------------------------------------
|
||||
// Generic Varying
|
||||
// ----------------------------------------------
|
||||
it('Should extend Iterator 1', () => {
|
||||
type T = IterableIterator<any> extends IterableIterator<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.Any()), Type.Iterator(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Iterator 2', () => {
|
||||
type T = IterableIterator<string> extends IterableIterator<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.String()), Type.Iterator(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Iterator 3', () => {
|
||||
type T = IterableIterator<'hello'> extends IterableIterator<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.Literal('hello')), Type.Iterator(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Iterator 4', () => {
|
||||
type T = IterableIterator<string> extends IterableIterator<'hello'> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.String()), Type.Iterator(Type.Literal('hello')))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Iterator 5', () => {
|
||||
type T = IterableIterator<string> extends IterableIterator<'hello' | number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.String()), Type.Iterator(Type.Union([Type.Literal('hello'), Type.Number()])))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Iterator 6', () => {
|
||||
type T = IterableIterator<'hello' | number> extends IterableIterator<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.Union([Type.Literal('hello'), Type.Number()])), Type.Iterator(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// --------------------------------------------------------------------
|
||||
// Structural
|
||||
// --------------------------------------------------------------------
|
||||
it('Should extends Any 1', () => {
|
||||
type T = IterableIterator<number> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extends Any 2', () => {
|
||||
type T = any extends IterableIterator<number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Iterator(Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extends Unknown 1', () => {
|
||||
type T = IterableIterator<number> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.Number()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extends Unknown 2', () => {
|
||||
type T = unknown extends IterableIterator<number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Iterator(Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extends Never 1', () => {
|
||||
type T = IterableIterator<number> extends never ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Iterator(Type.Number()), Type.Never())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extends Never 2', () => {
|
||||
type T = never extends IterableIterator<number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Never(), Type.Iterator(Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
})
|
||||
264
test/runtime/type/extends/literal.ts
Normal file
264
test/runtime/type/extends/literal.ts
Normal file
@@ -0,0 +1,264 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Literal', () => {
|
||||
// -------------------------------------------------------------------
|
||||
// String Literal
|
||||
// -------------------------------------------------------------------
|
||||
it('Should extend Any (String)', () => {
|
||||
type T = 'hello' extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown (String)', () => {
|
||||
type T = 'hello' extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String (String)', () => {
|
||||
type T = 'hello' extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Boolean (String)', () => {
|
||||
type T = 'hello' extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number (String)', () => {
|
||||
type T = 'hello' extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer (String)', () => {
|
||||
type T = 'hello' extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array (String)', () => {
|
||||
type T = 'hello' extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple (String)', () => {
|
||||
type T = 'hello' extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1 (String)', () => {
|
||||
type T = 'hello' extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2 (String)', () => {
|
||||
type T = 'hello' extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1 (String)', () => {
|
||||
type T = 'hello' extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2 (String)', () => {
|
||||
type T = 'hello' extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3 (String)', () => {
|
||||
type T = 'hello' extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null (String)', () => {
|
||||
type T = 'hello' extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined (String)', () => {
|
||||
type T = 'hello' extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// -------------------------------------------------------------------
|
||||
// Number Literal
|
||||
// -------------------------------------------------------------------
|
||||
it('Should extend Any (Number)', () => {
|
||||
type T = 10 extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown (Number)', () => {
|
||||
type T = 10 extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String (Number)', () => {
|
||||
type T = 10 extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean (Number)', () => {
|
||||
type T = 10 extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number (Number)', () => {
|
||||
type T = 10 extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Integer (Number)', () => {
|
||||
type T = 10 extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array (Number)', () => {
|
||||
type T = 10 extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple (Number)', () => {
|
||||
type T = 10 extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1 (Number)', () => {
|
||||
type T = 10 extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2 (Number)', () => {
|
||||
type T = 10 extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1 (Number)', () => {
|
||||
type T = 10 extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2 (Number)', () => {
|
||||
type T = 10 extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3 (Number)', () => {
|
||||
type T = 10 extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null (Number)', () => {
|
||||
type T = 10 extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined (Number)', () => {
|
||||
type T = 10 extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// -------------------------------------------------------------------
|
||||
// Boolean Literal
|
||||
// -------------------------------------------------------------------
|
||||
it('Should extend Any (Boolean)', () => {
|
||||
type T = true extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown (Boolean)', () => {
|
||||
type T = true extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String (Boolean)', () => {
|
||||
type T = true extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean (Boolean)', () => {
|
||||
type T = true extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Number (Boolean)', () => {
|
||||
type T = true extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer (Boolean)', () => {
|
||||
type T = true extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array (Boolean)', () => {
|
||||
type T = true extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple (Boolean)', () => {
|
||||
type T = true extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 1', () => {
|
||||
type T = 'hello' extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal('hello'), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 2', () => {
|
||||
type T = 10 extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(10), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 3', () => {
|
||||
type T = true extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1 (Boolean)', () => {
|
||||
type T = true extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2 (Boolean)', () => {
|
||||
type T = true extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1 (Boolean)', () => {
|
||||
type T = true extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2 (Boolean)', () => {
|
||||
type T = true extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3 (Boolean)', () => {
|
||||
type T = true extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null (Boolean)', () => {
|
||||
type T = true extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined (Boolean)', () => {
|
||||
type T = true extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = true extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = true extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Literal(true), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
144
test/runtime/type/extends/not.ts
Normal file
144
test/runtime/type/extends/not.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Note: Not is equivalent to Unknown with the exception of nested negation.
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('type/extends/Not', () => {
|
||||
// -------------------------------------------------------------------------
|
||||
// Issue: type T = number extends not number ? true : false // true
|
||||
// type T = number extends unknown ? true : false // true
|
||||
//
|
||||
// TypeScript does not support type negation. The best TypeBox can do is
|
||||
// treat "not" as "unknown". From this standpoint, the extends assignability
|
||||
// check needs to return true for the following case to keep TypeBox aligned
|
||||
// with TypeScript static inference.
|
||||
// -------------------------------------------------------------------------
|
||||
it('Should extend with unknown assignability check', () => {
|
||||
const A = Type.Number()
|
||||
const B = Type.Not(Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True) // we would expect false
|
||||
})
|
||||
// ---------------------------------------------------------------------------
|
||||
// Nested
|
||||
// ---------------------------------------------------------------------------
|
||||
it('Should extend with nested negation', () => {
|
||||
const T1 = Type.String()
|
||||
const T2 = Type.Not(T1)
|
||||
const T3 = Type.Not(T2)
|
||||
const T4 = Type.Not(T3)
|
||||
const T5 = Type.Not(T4)
|
||||
|
||||
const R1 = ExtendsCheck(T1, Type.String())
|
||||
const R2 = ExtendsCheck(T2, Type.String())
|
||||
const R3 = ExtendsCheck(T3, Type.String())
|
||||
const R4 = ExtendsCheck(T4, Type.String())
|
||||
const R5 = ExtendsCheck(T5, Type.String())
|
||||
|
||||
Assert.IsEqual(R1, ExtendsResult.True)
|
||||
Assert.IsEqual(R2, ExtendsResult.False)
|
||||
Assert.IsEqual(R3, ExtendsResult.True)
|
||||
Assert.IsEqual(R4, ExtendsResult.False)
|
||||
Assert.IsEqual(R5, ExtendsResult.True)
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Not as Unknown Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
it('Should extend Any', () => {
|
||||
type T = unknown extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = unknown extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = unknown extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = unknown extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = unknown extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = unknown extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = unknown extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = unknown extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = unknown extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = unknown extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = unknown extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = unknown extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = unknown extends any | number ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = unknown extends unknown | number ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Unknown(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = unknown extends unknown | any ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Unknown(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = unknown extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = unknown extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = unknown extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = unknown extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Not(Type.Number()), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
100
test/runtime/type/extends/null.ts
Normal file
100
test/runtime/type/extends/null.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Null', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = null extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = null extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = null extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = null extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = null extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = null extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = null extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = null extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = null extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = null extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = null extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = null extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = null extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = null extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = null extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = null extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = null extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = null extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = null extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Null(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
95
test/runtime/type/extends/number.ts
Normal file
95
test/runtime/type/extends/number.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Number', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = number extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = number extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = number extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = number extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = number extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = number extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = number extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = number extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = number extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = number extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = number extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = number extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = number extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = number extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = number extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = number extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
227
test/runtime/type/extends/object.ts
Normal file
227
test/runtime/type/extends/object.ts
Normal file
@@ -0,0 +1,227 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Object', () => {
|
||||
// ----------------------------------------------------------
|
||||
// Object
|
||||
// ----------------------------------------------------------
|
||||
it('Should extend Object 1', () => {
|
||||
type T = { x: number; y: number } extends { x: number } ? 1 : 2
|
||||
const A = Type.Object({ x: Type.Number(), y: Type.Number() })
|
||||
const B = Type.Object({ x: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = { x: number } extends { x: number; y: number } ? 1 : 2
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ x: Type.Number(), y: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = { x: number; y: string } extends { x: number } ? 1 : 2
|
||||
const A = Type.Object({ x: Type.Number(), y: Type.String() })
|
||||
const B = Type.Object({ x: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 4', () => {
|
||||
type T = { x: number } extends { x: number; y: string } ? 1 : 2
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ x: Type.Number(), y: Type.String() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 5', () => {
|
||||
type T = { x: number | string } extends { x: number } ? 1 : 2
|
||||
const A = Type.Object({ x: Type.Union([Type.Number(), Type.String()]) })
|
||||
const B = Type.Object({ x: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 6', () => {
|
||||
type T = { x: number } extends { x: number | string } ? 1 : 2
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ x: Type.Union([Type.Number(), Type.String()]) })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
// ----------------------------------------------------------
|
||||
// Record
|
||||
// ----------------------------------------------------------
|
||||
it('Should extend Record 2', () => {
|
||||
type T = { a: number; b: number } extends Record<string, number> ? 1 : 2
|
||||
const A = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const B = Type.Record(Type.String(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 3', () => {
|
||||
type T = { a: number; b: number } extends Record<number, number> ? 1 : 2
|
||||
const A = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const B = Type.Record(Type.Number(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 4', () => {
|
||||
type T = { a: number; b: number } extends Record<'a' | 'b', number> ? 1 : 2
|
||||
const A = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 5', () => {
|
||||
type T = { a: number; b: number } extends Record<'a' | 'b', number> ? 1 : 2
|
||||
const A = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const B = Type.Record(Type.String(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 6', () => {
|
||||
type T = { a: number; b: number } extends Record<'a' | 'b', number> ? 1 : 2
|
||||
const A = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const B = Type.Record(Type.Number(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
// ----------------------------------------------------------
|
||||
// Standard
|
||||
// ----------------------------------------------------------
|
||||
it('Should extend Any', () => {
|
||||
type T = { a: number } extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = { a: number } extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = { a: number } extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = { a: number } extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = { a: number } extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = { a: number } extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = { a: number } extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = { a: number } extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = { a: number } extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Object({ a: Type.Literal(10) }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = { a: number } extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = { a: number } extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Union([Type.Null(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = { a: number } extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = { a: number } extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = { a: number } extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = { a: number } extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = { a: number } extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = { a: number } extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.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 = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(C, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend optional 2', () => {
|
||||
const A = Type.Object({ a: Type.Number() })
|
||||
const B = Type.Object({ a: Type.Optional(Type.Number()) })
|
||||
const C = ExtendsCheck(B, A)
|
||||
Assert.IsEqual(C, ExtendsResult.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 = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.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 = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.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 = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
})
|
||||
209
test/runtime/type/extends/promise.ts
Normal file
209
test/runtime/type/extends/promise.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Promise', () => {
|
||||
// ----------------------------------------------
|
||||
// Generic Varying
|
||||
// ----------------------------------------------
|
||||
it('Should extend Promise Varying 1', () => {
|
||||
type T = Promise<any> extends Promise<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Promise(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Promise Varying 2', () => {
|
||||
type T = Promise<string> extends Promise<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.String()), Type.Promise(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Promise Varying 3', () => {
|
||||
type T = Promise<any> extends Promise<string> ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Promise(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Promise Varying 4', () => {
|
||||
type T = Promise<number> extends Promise<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Promise(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// ----------------------------------------------
|
||||
// Any
|
||||
// ----------------------------------------------
|
||||
it('Should extend Any', () => {
|
||||
type T = Promise<any> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = Promise<any> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = Promise<any> extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = Promise<any> extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = Promise<any> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = Promise<any> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = Promise<any> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = Promise<any> extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = Promise<any> extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = Promise<any> extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = Promise<any> extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = Promise<any> extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = Promise<any> extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = Promise<any> extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = Promise<any> extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = Promise<any> extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = Promise<any> extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// ----------------------------------------------
|
||||
// Constrained
|
||||
// ----------------------------------------------
|
||||
it('Should extend constrained Any', () => {
|
||||
type T = Promise<number> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Unknown', () => {
|
||||
type T = Promise<number> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained String', () => {
|
||||
type T = Promise<number> extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Boolean', () => {
|
||||
type T = Promise<number> extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Number', () => {
|
||||
type T = Promise<number> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Integer', () => {
|
||||
type T = Promise<number> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Array', () => {
|
||||
type T = Promise<number> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Tuple', () => {
|
||||
type T = Promise<number> extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Object 1', () => {
|
||||
type T = Promise<number> extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Object 2', () => {
|
||||
type T = Promise<number> extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Object 3', () => {
|
||||
type T = Promise<number> extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Union 1', () => {
|
||||
type T = Promise<number> extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Union 2', () => {
|
||||
type T = Promise<number> extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend constrained Union 2', () => {
|
||||
type T = Promise<number> extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Null', () => {
|
||||
type T = Promise<number> extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend constrained Undefined', () => {
|
||||
type T = Promise<number> extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = Promise<number> extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = Promise<number> extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
199
test/runtime/type/extends/record.ts
Normal file
199
test/runtime/type/extends/record.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Record', () => {
|
||||
it('Should extend Record 1', () => {
|
||||
type T = Record<'a' | 'b', number> extends { a: number; b: number } ? 1 : 2
|
||||
const A = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const B = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 2', () => {
|
||||
type T = Record<string, number> extends { a: number; b: number } ? 1 : 2
|
||||
const A = Type.Record(Type.String(), Type.Number())
|
||||
const B = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 3', () => {
|
||||
type T = Record<number, number> extends { a: number; b: number } ? 1 : 2
|
||||
const A = Type.Record(Type.Number(), Type.Number())
|
||||
const B = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 4', () => {
|
||||
type T = Record<'a' | 'b', number> extends { a: number; b: number } ? 1 : 2
|
||||
const A = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const B = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 5', () => {
|
||||
type T = Record<'a' | 'b', number> extends { a: number; b: number } ? 1 : 2
|
||||
const A = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const B = Type.Object({ a: Type.Number(), b: Type.Number() })
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 6', () => {
|
||||
type T = Record<string, number> extends Record<'a' | 'b', number> ? true : false
|
||||
const A = Type.Record(Type.String(), Type.Number())
|
||||
const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 7', () => {
|
||||
type T = Record<string, number> extends Record<string, number> ? 1 : 2
|
||||
const A = Type.Record(Type.String(), Type.Number())
|
||||
const B = Type.Record(Type.String(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 8', () => {
|
||||
type T = Record<string, number> extends Record<number, number> ? 1 : 2
|
||||
const A = Type.Record(Type.String(), Type.Number())
|
||||
const B = Type.Record(Type.Number(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 9', () => {
|
||||
type T = Record<number, number> extends Record<'a' | 'b', number> ? 1 : 2
|
||||
const A = Type.Record(Type.Number(), Type.Number())
|
||||
const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 10', () => {
|
||||
type T = Record<number, number> extends Record<string, number> ? 1 : 2
|
||||
const A = Type.Record(Type.Number(), Type.Number())
|
||||
const B = Type.Record(Type.String(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 11', () => {
|
||||
type T = Record<number, number> extends Record<number, number> ? 1 : 2
|
||||
const A = Type.Record(Type.Number(), Type.Number())
|
||||
const B = Type.Record(Type.Number(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
// -----
|
||||
it('Should extend Record 12', () => {
|
||||
type T = Record<string, number> extends Record<number, number> ? 1 : 2
|
||||
const A = Type.Record(Type.String(), Type.Number())
|
||||
const B = Type.Record(Type.Integer(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 13', () => {
|
||||
type T = Record<number, number> extends Record<'a' | 'b', number> ? 1 : 2
|
||||
const A = Type.Record(Type.Integer(), Type.Number())
|
||||
const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 14', () => {
|
||||
type T = Record<number, number> extends Record<string, number> ? 1 : 2
|
||||
const A = Type.Record(Type.Integer(), Type.Number())
|
||||
const B = Type.Record(Type.String(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 15', () => {
|
||||
type T = Record<number, number> extends Record<number, number> ? 1 : 2
|
||||
const A = Type.Record(Type.Integer(), Type.Number())
|
||||
const B = Type.Record(Type.Integer(), Type.Number())
|
||||
const R = ExtendsCheck(A, B)
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
// -------------------------------------------------------------------
|
||||
// Standard
|
||||
// -------------------------------------------------------------------
|
||||
it('Should extend Any', () => {
|
||||
type T = Record<number, number> extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = Record<number, number> extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = Record<number, number> extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = Record<number, number> extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = Record<number, number> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = Record<number, number> extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = Record<number, number> extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = Record<number, number> extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = Record<number, number> extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = Record<number, number> extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = Record<number, number> extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = Record<number, number> extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = Record<number, number> extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = Record<number, number> extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = Record<number, number> extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = Record<number, number> extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = Record<number, number> extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
113
test/runtime/type/extends/regexp.ts
Normal file
113
test/runtime/type/extends/regexp.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Note: RegExp infers as type String
|
||||
// ------------------------------------------------------------------
|
||||
describe('type/extends/RegExp', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = string extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = string extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = string extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.RegExp(/xyz/))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = string extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = string extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = string extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = string extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = string extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 1', () => {
|
||||
type T = string extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 2', () => {
|
||||
type T = string extends Record<number, unknown> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.Unknown()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 3', () => {
|
||||
type T = string extends Record<number, string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.RegExp(/xyz/)))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 4', () => {
|
||||
type T = string extends Record<number, number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = string extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = string extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = number extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Number(), Type.RegExp(/xyz/)]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = number extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = number extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = number extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = number extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = number extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
110
test/runtime/type/extends/string.ts
Normal file
110
test/runtime/type/extends/string.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/String', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = string extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = string extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = string extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = string extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = string extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = string extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = string extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = string extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 1', () => {
|
||||
type T = string extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 2', () => {
|
||||
type T = string extends Record<number, unknown> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Unknown()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 3', () => {
|
||||
type T = string extends Record<number, string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 4', () => {
|
||||
type T = string extends Record<number, number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = string extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = string extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = number extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = number extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = number extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = number extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = number extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = number extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Number(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
105
test/runtime/type/extends/symbol.ts
Normal file
105
test/runtime/type/extends/symbol.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Symbol', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = symbol extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = symbol extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = symbol extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = symbol extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = symbol extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = symbol extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = symbol extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = symbol extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = symbol extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = symbol extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = symbol extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Object({ a: Type.Literal(10) }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = symbol extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = symbol extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = symbol extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = symbol extends boolean | symbol ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Boolean(), Type.Symbol()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = symbol extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = symbol extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = symbol extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = symbol extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Symbol', () => {
|
||||
type T = symbol extends symbol ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Symbol(), Type.Symbol())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
})
|
||||
161
test/runtime/type/extends/template-literal.ts
Normal file
161
test/runtime/type/extends/template-literal.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/TemplateLiteral', () => {
|
||||
// -------------------------------------------------------------------
|
||||
// String Literal 'hello'
|
||||
// -------------------------------------------------------------------
|
||||
it('Should extend Any (hello)', () => {
|
||||
type T = 'hello' extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown (hello)', () => {
|
||||
type T = 'hello' extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String (hello)', () => {
|
||||
type T = 'hello' extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Boolean (hello)', () => {
|
||||
type T = 'hello' extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number (hello)', () => {
|
||||
type T = 'hello' extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer (hello)', () => {
|
||||
type T = 'hello' extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array (hello)', () => {
|
||||
type T = 'hello' extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple (hello)', () => {
|
||||
type T = 'hello' extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1 (hello)', () => {
|
||||
type T = 'hello' extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2 (hello)', () => {
|
||||
type T = 'hello' extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1 (hello)', () => {
|
||||
type T = 'hello' extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2 (hello)', () => {
|
||||
type T = 'hello' extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3 (hello)', () => {
|
||||
type T = 'hello' extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null (hello)', () => {
|
||||
type T = 'hello' extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined (hello)', () => {
|
||||
type T = 'hello' extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
// -------------------------------------------------------------------
|
||||
// String Literal 'hello' | 'world'
|
||||
// -------------------------------------------------------------------
|
||||
it('Should extend Any (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Boolean (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1 (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2 (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1 (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2 (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3 (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined (hello | world)', () => {
|
||||
type T = 'hello' | 'world' extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
160
test/runtime/type/extends/tuple.ts
Normal file
160
test/runtime/type/extends/tuple.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Tuple', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = [string, number] extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = [string, number] extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = [string, number] extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = [string, number] extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = [string, number] extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = [string, number] extends Array<any> ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = [string, number] extends Array<string> ? 1 : 2 // 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 3', () => {
|
||||
type T = [string, number] extends Array<string | number> ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.Union([Type.String(), Type.Number()])))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Array 4', () => {
|
||||
type T = [string, number] extends Array<string | number | boolean> ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.Union([Type.String(), Type.Number(), Type.Boolean()])))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Tuple 1', () => {
|
||||
type T = [string, number] extends [string, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.String(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Tuple 2', () => {
|
||||
type T = [string, number] extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple 3', () => {
|
||||
type T = [string, any] extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Any()]), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple 4', () => {
|
||||
type T = [string, number] extends [string, any] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.String(), Type.Any()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Tuple 5', () => {
|
||||
type T = [string, unknown] extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Unknown()]), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple 6', () => {
|
||||
type T = [string, number] extends [string, unknown] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.String(), Type.Unknown()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Tuple 7', () => {
|
||||
type T = [] extends [string, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([]), Type.Tuple([Type.String(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple 8', () => {
|
||||
type T = [string, number] extends [] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record 1', () => {
|
||||
type T = [string, number] extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 2', () => {
|
||||
type T = [string, number] extends Record<number, unknown> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Unknown()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 3', () => {
|
||||
type T = [string, number] extends Record<number, string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Record 4', () => {
|
||||
type T = [string, number] extends Record<number, number> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Number()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = [string, number] extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = [string, number] extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = [string, number] extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = [string, number] extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = [string, number] extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = [string, number] extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = [string, number] extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = [string, number] extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = [string, number] extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = [string, number] extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
95
test/runtime/type/extends/uint8array.ts
Normal file
95
test/runtime/type/extends/uint8array.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Uint8Array', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = Uint8Array extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = Uint8Array extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = Uint8Array extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = Uint8Array extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = Uint8Array extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = Uint8Array extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = Uint8Array extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = Uint8Array extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Record', () => {
|
||||
type T = Uint8Array extends Record<number, any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Record(Type.Number(), Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = Uint8Array extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = Uint8Array extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = Uint8Array extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = Uint8Array extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = Uint8Array extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = Uint8Array extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = Uint8Array extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = Uint8Array extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = Uint8Array extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Uint8Array(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
90
test/runtime/type/extends/undefined.ts
Normal file
90
test/runtime/type/extends/undefined.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Undefined', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = undefined extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = undefined extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = undefined extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = undefined extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = undefined extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = undefined extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = undefined extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = undefined extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = undefined extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = undefined extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = undefined extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = undefined extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = undefined extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = undefined extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = undefined extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = undefined extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = undefined extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Undefined(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
135
test/runtime/type/extends/union.ts
Normal file
135
test/runtime/type/extends/union.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Union', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = number | string extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = number | string extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = number | string extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = number | string extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = number | string extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array', () => {
|
||||
type T = number | string extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = number | string extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = number | string extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Object({}, { additionalProperties: false }))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = number | string extends { a: 10 } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = number | string extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = number | string extends any | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Union([Type.Any(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = number | string extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = any | boolean extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Union 5', () => {
|
||||
type T = any | string extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Union 6', () => {
|
||||
type T = any | {} extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Union 7', () => {
|
||||
type T = any extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.Union)
|
||||
})
|
||||
it('Should extend Union 8', () => {
|
||||
type T = unknown | string extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Unknown(), Type.String()]), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 9', () => {
|
||||
type T = unknown extends boolean | number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Boolean(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = number | string extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = number | string extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = number | string extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void 2', () => {
|
||||
type T = number | string | void extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = number | string | void extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date 2', () => {
|
||||
type T = Date | number | string | void extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Date(), Type.Number(), Type.String()]), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend BigInt', () => {
|
||||
type T = bigint | number | string | void extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.BigInt(), Type.Number(), Type.String()]), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Symbol', () => {
|
||||
type T = symbol | number | string | void extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Union([Type.Symbol(), Type.Number(), Type.String()]), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
100
test/runtime/type/extends/unknown.ts
Normal file
100
test/runtime/type/extends/unknown.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Unknown', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = unknown extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = unknown extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = unknown extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = unknown extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = unknown extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = unknown extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = unknown extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = unknown extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = unknown extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = unknown extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = unknown extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = unknown extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = unknown extends any | number ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = unknown extends unknown | number ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Unknown(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = unknown extends unknown | any ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Unknown(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = unknown extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = unknown extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = unknown extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = unknown extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Unknown(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
105
test/runtime/type/extends/void.ts
Normal file
105
test/runtime/type/extends/void.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('type/extends/Void', () => {
|
||||
it('Should extend Any', () => {
|
||||
type T = void extends any ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Any())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Unknown', () => {
|
||||
type T = void extends unknown ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Unknown())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend String', () => {
|
||||
type T = void extends string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.String())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Boolean', () => {
|
||||
type T = void extends boolean ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Boolean())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Number', () => {
|
||||
type T = void extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Number())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Integer', () => {
|
||||
type T = void extends number ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Integer())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 1', () => {
|
||||
type T = void extends Array<any> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Array(Type.Any()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Array 2', () => {
|
||||
type T = void extends Array<string> ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Array(Type.String()))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Tuple', () => {
|
||||
type T = void extends [number, number] ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 1', () => {
|
||||
type T = void extends object ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 2', () => {
|
||||
type T = void extends {} ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Object({}))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Object 3', () => {
|
||||
type T = void extends { a: number } ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Object({ a: Type.Number() }))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 1', () => {
|
||||
type T = void extends number | string ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Union([Type.Number(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Union 2', () => {
|
||||
type T = void extends any | number ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Void(), Type.Union([Type.Any(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 3', () => {
|
||||
type T = void extends unknown | number ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Void(), Type.Union([Type.Unknown(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Union 4', () => {
|
||||
type T = void extends unknown | any ? 1 : 2 // 1
|
||||
const R = ExtendsCheck(Type.Void(), Type.Union([Type.Unknown(), Type.String()]))
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Null', () => {
|
||||
type T = void extends null ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Null())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Undefined', () => {
|
||||
type T = void extends undefined ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Undefined())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
it('Should extend Void', () => {
|
||||
type T = void extends void ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Void())
|
||||
Assert.IsEqual(R, ExtendsResult.True)
|
||||
})
|
||||
it('Should extend Date', () => {
|
||||
type T = void extends Date ? 1 : 2
|
||||
const R = ExtendsCheck(Type.Void(), Type.Date())
|
||||
Assert.IsEqual(R, ExtendsResult.False)
|
||||
})
|
||||
})
|
||||
3
test/runtime/type/guard/index.ts
Normal file
3
test/runtime/type/guard/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import './type/index'
|
||||
import './kind/index'
|
||||
import './value/index'
|
||||
14
test/runtime/type/guard/kind/any.ts
Normal file
14
test/runtime/type/guard/kind/any.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TAny', () => {
|
||||
it('Should guard for TAny', () => {
|
||||
const R = KindGuard.IsAny(Type.Any())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TAny', () => {
|
||||
const R = KindGuard.IsAny(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/argument.ts
Normal file
14
test/runtime/type/guard/kind/argument.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TArgument', () => {
|
||||
it('Should guard for TArgument', () => {
|
||||
const R = KindGuard.IsArgument(Type.Argument(0))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TArgument', () => {
|
||||
const R = KindGuard.IsArgument(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/array.ts
Normal file
14
test/runtime/type/guard/kind/array.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TArray', () => {
|
||||
it('Should guard for TArray', () => {
|
||||
const R = KindGuard.IsArray(Type.Array(Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TArray', () => {
|
||||
const R = KindGuard.IsArray(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
16
test/runtime/type/guard/kind/async-iterator.ts
Normal file
16
test/runtime/type/guard/kind/async-iterator.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TAsyncIterator', () => {
|
||||
it('Should guard for TAsyncIterator', () => {
|
||||
const T = Type.AsyncIterator(Type.Any())
|
||||
const R = KindGuard.IsAsyncIterator(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TAsyncIterator', () => {
|
||||
const T = null
|
||||
const R = KindGuard.IsAsyncIterator(T)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
41
test/runtime/type/guard/kind/awaited.ts
Normal file
41
test/runtime/type/guard/kind/awaited.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/Awaited', () => {
|
||||
it('Should guard for Awaited 1', () => {
|
||||
const T = Type.Awaited(Type.String())
|
||||
const R = KindGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for Awaited 2', () => {
|
||||
const T = Type.Awaited(Type.Promise(Type.String()))
|
||||
const R = KindGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for Awaited 3', () => {
|
||||
const T = Type.Awaited(Type.Awaited(Type.Promise(Type.String())))
|
||||
const R = KindGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for Awaited 4', () => {
|
||||
const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String()))]))
|
||||
Assert.IsTrue(KindGuard.IsString(T))
|
||||
})
|
||||
it('Should guard for Awaited 5', () => {
|
||||
const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String())), Type.Number()]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.anyOf[1]))
|
||||
})
|
||||
it('Should guard for Awaited 6', () => {
|
||||
const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String()))]))
|
||||
Assert.IsTrue(KindGuard.IsString(T))
|
||||
})
|
||||
it('Should guard for Awaited 7', () => {
|
||||
const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String())), Type.Number()]))
|
||||
Assert.IsTrue(KindGuard.IsIntersect(T))
|
||||
Assert.IsTrue(KindGuard.IsString(T.allOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.allOf[1]))
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/bigint.ts
Normal file
14
test/runtime/type/guard/kind/bigint.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TBigInt', () => {
|
||||
it('Should guard for TBigInt', () => {
|
||||
const R = KindGuard.IsBigInt(Type.BigInt())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TBigInt', () => {
|
||||
const R = KindGuard.IsBigInt(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/boolean.ts
Normal file
14
test/runtime/type/guard/kind/boolean.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TBoolean', () => {
|
||||
it('Should guard for TBoolean', () => {
|
||||
const R = KindGuard.IsBoolean(Type.Boolean())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TBoolean', () => {
|
||||
const R = KindGuard.IsBoolean(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/kind/capitalize.ts
Normal file
33
test/runtime/type/guard/kind/capitalize.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { KindGuard, Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/Capitalize', () => {
|
||||
it('Should guard for Capitalize 1', () => {
|
||||
const T = Type.Capitalize(Type.Literal('hello'), { $id: 'hello', foo: 1 })
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'Hello')
|
||||
Assert.IsEqual(T.$id, 'hello')
|
||||
Assert.IsEqual(T.foo, 1)
|
||||
})
|
||||
it('Should guard for Capitalize 2', () => {
|
||||
const T = Type.Capitalize(Type.Literal('hello'))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'Hello')
|
||||
})
|
||||
it('Should guard for Capitalize 3', () => {
|
||||
const T = Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'Hello')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'World')
|
||||
})
|
||||
it('Should guard for Capitalize 4', () => {
|
||||
const T = Type.Capitalize(Type.TemplateLiteral('hello${0|1}'))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
|
||||
})
|
||||
it('Should guard for Capitalize 5', () => {
|
||||
const T = Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
|
||||
})
|
||||
})
|
||||
165
test/runtime/type/guard/kind/composite.ts
Normal file
165
test/runtime/type/guard/kind/composite.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TComposite', () => {
|
||||
it('Should guard for distinct properties', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })])
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.y))
|
||||
})
|
||||
it('Should guard for overlapping properties', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() })])
|
||||
Assert.IsTrue(KindGuard.IsIntersect(T.properties.x))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x.allOf[0]))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x.allOf[1]))
|
||||
})
|
||||
it('Should not produce optional property if all properties are not optional', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() })])
|
||||
Assert.IsFalse(KindGuard.IsOptional(T.properties.x))
|
||||
})
|
||||
// Note for: https://github.com/sinclairzx81/typebox/issues/419
|
||||
// Determining if a composite property is optional requires a deep check for all properties gathered during a indexed access
|
||||
// call. Currently, there isn't a trivial way to perform this check without running into possibly infinite instantiation issues.
|
||||
// The optional check is only specific to overlapping properties. Singular properties will continue to work as expected. The
|
||||
// rule is "if all composite properties for a key are optional, then the composite property is optional". Defer this test and
|
||||
// document as minor breaking change.
|
||||
//
|
||||
it('Should produce optional property if all composited properties are optional', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.Number()) }),
|
||||
Type.Object({ x: Type.Optional(Type.Number()) })
|
||||
])
|
||||
Assert.IsTrue(KindGuard.IsOptional(T.properties.x))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should produce required property if some composited properties are not optional', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.Number()) }),
|
||||
Type.Object({ x: Type.Number() })
|
||||
])
|
||||
Assert.IsFalse(KindGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(T.required!.includes('x'))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should preserve single optional property', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.Number()) }),
|
||||
])
|
||||
Assert.IsTrue(KindGuard.IsOptional(T.properties.x))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect
|
||||
// ----------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 1', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() }),
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number()
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 2', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ x: Type.Number() }),
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Intersect([Type.Intersect([Type.Number(), Type.Number()]), Type.Number()])
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 3', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Number(),
|
||||
Type.Boolean()
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 4', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Number(),
|
||||
Type.Boolean(),
|
||||
Type.Object({ x: Type.String() })
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.String()
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 5', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.String()) }),
|
||||
Type.Object({ x: Type.String() })
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Intersect([Type.String(), Type.String()])
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 6', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.String()) }),
|
||||
Type.Object({ x: Type.Optional(Type.String()) })
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Optional(Type.Intersect([Type.String(), Type.String()]))
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Union
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/789
|
||||
// prettier-ignore
|
||||
it('Should composite Union 1 (non-overlapping)', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Union([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() }),
|
||||
]),
|
||||
Type.Union([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
z: Type.Number()
|
||||
}))
|
||||
})
|
||||
// https://github.com/sinclairzx81/typebox/issues/789
|
||||
// prettier-ignore
|
||||
it('Should composite Union 2 (overlapping)', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Union([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ x: Type.Number() }),
|
||||
]),
|
||||
Type.Union([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Intersect([Type.Union([Type.Number(), Type.Number()]), Type.Number()])
|
||||
}))
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/kind/computed.ts
Normal file
33
test/runtime/type/guard/kind/computed.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TComputed', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Schema
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Schema', () => {
|
||||
const T = Type.Partial(Type.Ref('A'))
|
||||
Assert.IsTrue(KindGuard.IsComputed(T))
|
||||
Assert.IsTrue(KindGuard.IsSchema(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Record 1', () => {
|
||||
const T = Type.Record(Type.String(), Type.String())
|
||||
Assert.IsTrue(KindGuard.IsRecord(T))
|
||||
})
|
||||
it('Should guard for Record 3', () => {
|
||||
const T = Type.Record(Type.String(), Type.Ref('A'))
|
||||
Assert.IsTrue(KindGuard.IsRecord(T))
|
||||
})
|
||||
it('Should guard for Record 3', () => {
|
||||
const T = Type.Record(Type.String(), Type.Partial(Type.Ref('A')))
|
||||
Assert.IsTrue(KindGuard.IsRecord(T))
|
||||
})
|
||||
it('Should guard for Record 4', () => {
|
||||
const T = Type.Record(Type.Ref('A'), Type.String())
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
})
|
||||
124
test/runtime/type/guard/kind/const.ts
Normal file
124
test/runtime/type/guard/kind/const.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { KindGuard, ValueGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TConstT', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Identity Types
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TConst 1', () => {
|
||||
const T = Type.Const(undefined)
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsUndefined(T))
|
||||
})
|
||||
it('Should guard for TConst 2', () => {
|
||||
const T = Type.Const(null)
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsNull(T))
|
||||
})
|
||||
it('Should guard for TConst 3', () => {
|
||||
const T = Type.Const(Symbol())
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsSymbol(T))
|
||||
})
|
||||
it('Should guard for TConst 4', () => {
|
||||
const T = Type.Const(1 as const)
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 1)
|
||||
})
|
||||
it('Should guard for TConst 5', () => {
|
||||
const T = Type.Const('hello' as const)
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should guard for TConst 6', () => {
|
||||
const T = Type.Const(true as const)
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, true)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Complex Types
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TConst 7', () => {
|
||||
const T = Type.Const(100n as const)
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
// TS disparity because TLiteral does not support Bigint
|
||||
Assert.IsTrue(KindGuard.IsBigInt(T))
|
||||
})
|
||||
it('Should guard for TConst 8', () => {
|
||||
const T = Type.Const(new Date())
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsDate(T))
|
||||
})
|
||||
it('Should guard for TConst 9', () => {
|
||||
const T = Type.Const(new Uint8Array())
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsUint8Array(T))
|
||||
})
|
||||
it('Should guard for TConst 10', () => {
|
||||
const T = Type.Const(function () {})
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsFunction(T))
|
||||
Assert.IsTrue(T.parameters.length === 0)
|
||||
Assert.IsTrue(KindGuard.IsUnknown(T.returns))
|
||||
})
|
||||
it('Should guard for TConst 11', () => {
|
||||
const T = Type.Const(new (class {})())
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsObject(T))
|
||||
// Object types that are neither Date or Uint8Array evaluate as empty objects
|
||||
Assert.IsEqual(T.properties, {})
|
||||
})
|
||||
it('Should guard for TConst 12', () => {
|
||||
const T = Type.Const((function* (): any {})())
|
||||
const R = ValueGuard.IsIterator((function* (): any {})())
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsAny(T))
|
||||
})
|
||||
it('Should guard for TConst 13', () => {
|
||||
const T = Type.Const((async function* (): any {})())
|
||||
const R = ValueGuard.IsAsyncIterator((function* (): any {})())
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsAny(T))
|
||||
})
|
||||
it('Should guard for TConst 14', () => {
|
||||
const T = Type.Const({
|
||||
x: 1,
|
||||
y: {
|
||||
z: 2,
|
||||
},
|
||||
} as const)
|
||||
// root
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsObject(T))
|
||||
// x
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.properties.x))
|
||||
Assert.IsEqual(T.properties.x.const, 1)
|
||||
// y
|
||||
Assert.IsTrue(KindGuard.IsReadonly(T.properties.y))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.properties.y))
|
||||
// y.z
|
||||
Assert.IsTrue(KindGuard.IsReadonly(T.properties.y.properties.z))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.properties.y.properties.z))
|
||||
Assert.IsEqual(T.properties.y.properties.z.const, 2)
|
||||
})
|
||||
it('Should guard for TConst 15', () => {
|
||||
const T = Type.Const([1, 2, 3] as const)
|
||||
// root (arrays are always readonly as root)
|
||||
Assert.IsTrue(KindGuard.IsReadonly(T))
|
||||
Assert.IsTrue(KindGuard.IsTuple(T))
|
||||
Assert.IsTrue(T.items?.length === 3)
|
||||
// 0
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T.items![0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.items![0]))
|
||||
// 1
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T.items![1]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.items![1]))
|
||||
// 2
|
||||
Assert.IsFalse(KindGuard.IsReadonly(T.items![2]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.items![2]))
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/constructor.ts
Normal file
14
test/runtime/type/guard/kind/constructor.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TConstructor', () => {
|
||||
it('Should guard for TConstructor', () => {
|
||||
const R = KindGuard.IsConstructor(Type.Constructor([], Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TConstructor', () => {
|
||||
const R = KindGuard.IsConstructor(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/date.ts
Normal file
14
test/runtime/type/guard/kind/date.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TDate', () => {
|
||||
it('Should guard for TDate', () => {
|
||||
const R = KindGuard.IsDate(Type.Date())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TDate', () => {
|
||||
const R = KindGuard.IsDate(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
143
test/runtime/type/guard/kind/enum.ts
Normal file
143
test/runtime/type/guard/kind/enum.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TEnum', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Options
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Options 1', () => {
|
||||
const T = Type.Enum({ x: 1 }, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
it('Should guard for Options 2', () => {
|
||||
enum E {
|
||||
x,
|
||||
}
|
||||
const T = Type.Enum(E, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
it('Should guard for Options 3', () => {
|
||||
enum E {}
|
||||
const T = Type.Enum(E, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
it('Should guard for Options 4', () => {
|
||||
const T = Type.Enum({}, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Empty
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Empty 1', () => {
|
||||
const T = Type.Enum({})
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard for Empty 2', () => {
|
||||
enum E {}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Enum
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TEnum Enum 0', () => {
|
||||
enum E {}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard for TEnum Enum 1', () => {
|
||||
enum E {
|
||||
A,
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, E.A)
|
||||
})
|
||||
it('Should guard for TEnum Enum 2', () => {
|
||||
enum E {
|
||||
A = 1,
|
||||
B = 2,
|
||||
C = 3,
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, E.A)
|
||||
Assert.IsEqual(T.anyOf[1].const, E.B)
|
||||
Assert.IsEqual(T.anyOf[2].const, E.C)
|
||||
})
|
||||
it('Should guard for TEnum Enum 3', () => {
|
||||
enum E {
|
||||
A = 'X',
|
||||
B = 'Y',
|
||||
C = 'Z',
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, E.A)
|
||||
Assert.IsEqual(T.anyOf[1].const, E.B)
|
||||
Assert.IsEqual(T.anyOf[2].const, E.C)
|
||||
})
|
||||
it('Should guard for TEnum Enum 4', () => {
|
||||
enum E {
|
||||
A = 'X',
|
||||
B = 'Y',
|
||||
C = 'X',
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, E.A)
|
||||
Assert.IsEqual(T.anyOf[1].const, E.B)
|
||||
Assert.IsEqual(T.anyOf.length, 2)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Object Literal
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TEnum Object Literal 0', () => {
|
||||
const T = Type.Enum({})
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 1', () => {
|
||||
const T = Type.Enum({ A: 1 })
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 1)
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 2', () => {
|
||||
const T = Type.Enum({
|
||||
A: 1,
|
||||
B: 2,
|
||||
C: 3,
|
||||
})
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 1)
|
||||
Assert.IsEqual(T.anyOf[1].const, 2)
|
||||
Assert.IsEqual(T.anyOf[2].const, 3)
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 3', () => {
|
||||
const T = Type.Enum({
|
||||
A: 'X',
|
||||
B: 'Y',
|
||||
C: 'Z',
|
||||
})
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'X')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'Y')
|
||||
Assert.IsEqual(T.anyOf[2].const, 'Z')
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 4', () => {
|
||||
const T = Type.Enum({
|
||||
A: 'X',
|
||||
B: 'Y',
|
||||
C: 'X',
|
||||
})
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'X')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'Y')
|
||||
Assert.IsEqual(T.anyOf.length, 2)
|
||||
})
|
||||
})
|
||||
96
test/runtime/type/guard/kind/exclude.ts
Normal file
96
test/runtime/type/guard/kind/exclude.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TExclude', () => {
|
||||
it('Should exclude string from number', () => {
|
||||
const T = Type.Exclude(Type.String(), Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsString(T))
|
||||
})
|
||||
it('Should exclude string from string', () => {
|
||||
const T = Type.Exclude(Type.String(), Type.String())
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should exclude string | number | boolean from string', () => {
|
||||
const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String())
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsBoolean(T.anyOf[1]))
|
||||
})
|
||||
it('Should exclude string | number | boolean from string | boolean', () => {
|
||||
const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Boolean()]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T))
|
||||
})
|
||||
// ------------------------------------------------------------------------
|
||||
// TemplateLiteral | TemplateLiteral
|
||||
// ------------------------------------------------------------------------
|
||||
it('Should exclude TemplateLiteral | TemplateLiteral 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should exclude TemplateLiteral | TemplateLiteral 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(['C'].includes(T.const))
|
||||
})
|
||||
it('Should exclude TemplateLiteral | TemplateLiteral 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const))
|
||||
})
|
||||
// ------------------------------------------------------------------------
|
||||
// TemplateLiteral | Union 1
|
||||
// ------------------------------------------------------------------------
|
||||
it('Should exclude TemplateLiteral | Union 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should exclude TemplateLiteral | Union 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.Union([Type.Literal('A'), Type.Literal('B')])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(['C'].includes(T.const))
|
||||
})
|
||||
it('Should exclude TemplateLiteral | Union 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.Union([Type.Literal('A')])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const))
|
||||
})
|
||||
// ------------------------------------------------------------------------
|
||||
// Union | TemplateLiteral 1
|
||||
// ------------------------------------------------------------------------
|
||||
it('Should exclude Union | TemplateLiteral 1', () => {
|
||||
const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should exclude Union | TemplateLiteral 1', () => {
|
||||
const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(['C'].includes(T.const))
|
||||
})
|
||||
it('Should exclude Union | TemplateLiteral 1', () => {
|
||||
const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])])
|
||||
const T = Type.Exclude(A, B)
|
||||
Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const))
|
||||
})
|
||||
it('Should exclude with options', () => {
|
||||
const A = Type.String()
|
||||
const B = Type.String()
|
||||
const T = Type.Exclude(A, B, { foo: 'bar' })
|
||||
Assert.IsEqual(T.foo, 'bar')
|
||||
})
|
||||
})
|
||||
102
test/runtime/type/guard/kind/extract.ts
Normal file
102
test/runtime/type/guard/kind/extract.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TExtract', () => {
|
||||
it('Should extract string from number', () => {
|
||||
const T = Type.Extract(Type.String(), Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsNever(T))
|
||||
})
|
||||
it('Should extract string from string', () => {
|
||||
const T = Type.Extract(Type.String(), Type.String())
|
||||
Assert.IsTrue(KindGuard.IsString(T))
|
||||
})
|
||||
it('Should extract string | number | boolean from string', () => {
|
||||
const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String())
|
||||
Assert.IsTrue(KindGuard.IsString(T))
|
||||
})
|
||||
it('Should extract string | number | boolean from string | boolean', () => {
|
||||
const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Boolean()]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsBoolean(T.anyOf[1]))
|
||||
})
|
||||
// ------------------------------------------------------------------------
|
||||
// TemplateLiteral | TemplateLiteral
|
||||
// ------------------------------------------------------------------------
|
||||
it('Should extract TemplateLiteral | TemplateLiteral 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const))
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const))
|
||||
})
|
||||
it('Should extract TemplateLiteral | TemplateLiteral 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const))
|
||||
})
|
||||
it('Should extract TemplateLiteral | TemplateLiteral 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A'].includes(T.const))
|
||||
})
|
||||
// ------------------------------------------------------------------------
|
||||
// TemplateLiteral | Union 1
|
||||
// ------------------------------------------------------------------------
|
||||
it('Should extract TemplateLiteral | Union 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const))
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const))
|
||||
})
|
||||
it('Should extract TemplateLiteral | Union 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.Union([Type.Literal('A'), Type.Literal('B')])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const))
|
||||
})
|
||||
it('Should extract TemplateLiteral | Union 1', () => {
|
||||
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const B = Type.Union([Type.Literal('A')])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A'].includes(T.const))
|
||||
})
|
||||
// ------------------------------------------------------------------------
|
||||
// Union | TemplateLiteral 1
|
||||
// ------------------------------------------------------------------------
|
||||
it('Should extract Union | TemplateLiteral 1', () => {
|
||||
const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const))
|
||||
Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const))
|
||||
})
|
||||
it('Should extract Union | TemplateLiteral 1', () => {
|
||||
const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const))
|
||||
Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const))
|
||||
})
|
||||
it('Should extract Union | TemplateLiteral 1', () => {
|
||||
const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])
|
||||
const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])])
|
||||
const T = Type.Extract(A, B)
|
||||
Assert.IsTrue(['A'].includes(T.const))
|
||||
})
|
||||
it('Should extract with options', () => {
|
||||
const A = Type.String()
|
||||
const B = Type.String()
|
||||
const T = Type.Extract(A, B, { foo: 'bar' })
|
||||
Assert.IsEqual(T.foo, 'bar')
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/function.ts
Normal file
14
test/runtime/type/guard/kind/function.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TFunction', () => {
|
||||
it('Should guard for TFunction', () => {
|
||||
const R = KindGuard.IsFunction(Type.Function([], Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TFunction', () => {
|
||||
const R = KindGuard.IsFunction(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
291
test/runtime/type/guard/kind/import.ts
Normal file
291
test/runtime/type/guard/kind/import.ts
Normal file
@@ -0,0 +1,291 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TImport', () => {
|
||||
it('Should guard for TImport', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.String(),
|
||||
})
|
||||
const A = Module.Import('A')
|
||||
const N = A.$defs[A.$ref]
|
||||
Assert.IsTrue(KindGuard.IsImport(A))
|
||||
Assert.IsTrue(KindGuard.IsString(N))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Options
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TImport with Options 1', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.String(),
|
||||
})
|
||||
const A = Module.Import('A', { format: 'string' })
|
||||
const N = A.$defs[A.$ref]
|
||||
Assert.IsTrue(KindGuard.IsImport(A))
|
||||
Assert.IsTrue(KindGuard.IsString(N))
|
||||
Assert.IsTrue(N.format === 'string')
|
||||
})
|
||||
it('Should guard for TImport with Options 2', () => {
|
||||
const Module = Type.Module({
|
||||
R: Type.Object({ x: Type.Number() }),
|
||||
A: Type.Ref('R'),
|
||||
})
|
||||
const A = Module.Import('A', { test: 'test' })
|
||||
const N = A.$defs[A.$ref]
|
||||
Assert.IsTrue(KindGuard.IsImport(A))
|
||||
Assert.IsTrue(KindGuard.IsRef(N))
|
||||
Assert.IsTrue(N.test === 'test')
|
||||
})
|
||||
it('Should guard for TImport with Options 3', () => {
|
||||
const Module = Type.Module({
|
||||
R: Type.Object({ x: Type.Number() }),
|
||||
A: Type.Partial(Type.Ref('R')),
|
||||
})
|
||||
const A = Module.Import('A', { additionalProperties: false })
|
||||
const N = A.$defs[A.$ref]
|
||||
Assert.IsTrue(KindGuard.IsImport(A))
|
||||
Assert.IsTrue(KindGuard.IsObject(N))
|
||||
Assert.IsTrue(N.additionalProperties === false)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Awaited
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Awaited', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Promise(Type.String()),
|
||||
R: Type.Awaited(Type.Ref('T')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsString(T.$defs['R']))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Index (Note: Pending Reimplementation of Index)
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Index 2', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.String() }),
|
||||
I: Type.Literal('x'),
|
||||
R: Type.Index(Type.Ref('T'), Type.Ref('I')) as never, // fail
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R']))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Omit
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Omit 1', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.Number() }),
|
||||
R: Type.Omit(Type.Ref('T'), Type.Literal('x')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.y))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(T.$defs['R'].properties.x === undefined)
|
||||
})
|
||||
it('Should compute for Omit 2', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.Number() }),
|
||||
K: Type.Literal('x'),
|
||||
R: Type.Omit(Type.Ref('T'), Type.Ref('K')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.y))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(T.$defs['R'].properties.x === undefined)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Partial
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Partial', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number() }),
|
||||
R: Type.Partial(Type.Ref('T')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x))
|
||||
Assert.IsTrue(KindGuard.IsOptional(T.$defs['R'].properties.x))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Pick
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Pick 1', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.Number() }),
|
||||
R: Type.Pick(Type.Ref('T'), Type.Literal('x')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(T.$defs['R'].properties.y === undefined)
|
||||
})
|
||||
it('Should compute for Pick 2', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.Number() }),
|
||||
K: Type.Literal('x'),
|
||||
R: Type.Pick(Type.Ref('T'), Type.Ref('K')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(T.$defs['R'].properties.y === undefined)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Record 1', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.String() }),
|
||||
R: Type.Record(Type.String(), Type.Ref('T')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsRecord(T.$defs['R']))
|
||||
// note: TRecord<TSchema, TRef<...>> are not computed. Only the Key is
|
||||
// computed as TypeBox needs to make a deferred call to transform from
|
||||
// TRecord to TObject for finite keys.
|
||||
Assert.IsTrue(KindGuard.IsRef(T.$defs['R'].patternProperties['^(.*)$']))
|
||||
Assert.IsTrue(T.$defs['R'].patternProperties['^(.*)$'].$ref === 'T')
|
||||
})
|
||||
it('Should compute for Record 2', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Number(),
|
||||
R: Type.Record(Type.Union([Type.Literal('x'), Type.Literal('y')]), Type.Ref('T')),
|
||||
})
|
||||
// Retain reference if not computed
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsRef(T.$defs['R'].properties.x))
|
||||
Assert.IsTrue(KindGuard.IsRef(T.$defs['R'].properties.y))
|
||||
})
|
||||
it('Should compute for Record 3', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number() }),
|
||||
R: Type.Record(Type.Union([Type.Literal('x'), Type.Literal('y')]), Type.Partial(Type.Ref('T'))),
|
||||
})
|
||||
// Dereference if computed
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R'].properties.x))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R'].properties.y))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: Required
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Required', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Partial(Type.Object({ x: Type.Number() })),
|
||||
R: Type.Required(Type.Ref('T')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsObject(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x))
|
||||
Assert.IsFalse(KindGuard.IsOptional(T.$defs['R'].properties.x))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Computed: KeyOf
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for KeyOf', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({ x: Type.Number(), y: Type.String() }),
|
||||
R: Type.KeyOf(Type.Ref('T')),
|
||||
})
|
||||
const T = Module.Import('R')
|
||||
Assert.IsTrue(KindGuard.IsUnion(T.$defs['R']))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.$defs['R'].anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.$defs['R'].anyOf[1]))
|
||||
Assert.IsTrue(T.$defs['R'].anyOf[0].const === 'x')
|
||||
Assert.IsTrue(T.$defs['R'].anyOf[1].const === 'y')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Modifiers: 1
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Modifiers 1', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({
|
||||
x: Type.ReadonlyOptional(Type.Null()),
|
||||
y: Type.Readonly(Type.Null()),
|
||||
z: Type.Optional(Type.Null()),
|
||||
w: Type.Null(),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('T')
|
||||
const R = T.$defs[T.$ref]
|
||||
Assert.IsTrue(KindGuard.IsObject(R))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsReadonly(R.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsOptional(R.properties.x))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.y))
|
||||
Assert.IsTrue(KindGuard.IsReadonly(R.properties.y))
|
||||
Assert.IsFalse(KindGuard.IsOptional(R.properties.y))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.z))
|
||||
Assert.IsTrue(KindGuard.IsOptional(R.properties.z))
|
||||
Assert.IsFalse(KindGuard.IsReadonly(R.properties.z))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.w))
|
||||
Assert.IsFalse(KindGuard.IsOptional(R.properties.w))
|
||||
Assert.IsFalse(KindGuard.IsReadonly(R.properties.w))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Modifiers: 2
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Modifiers 2', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({
|
||||
x: Type.ReadonlyOptional(Type.Array(Type.Null())),
|
||||
y: Type.Readonly(Type.Array(Type.Null())),
|
||||
z: Type.Optional(Type.Array(Type.Null())),
|
||||
w: Type.Array(Type.Null()),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('T')
|
||||
const R = T.$defs[T.$ref]
|
||||
Assert.IsTrue(KindGuard.IsObject(R))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsArray(R.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.x.items))
|
||||
Assert.IsTrue(KindGuard.IsReadonly(R.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsOptional(R.properties.x))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsArray(R.properties.y))
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.y.items))
|
||||
Assert.IsTrue(KindGuard.IsReadonly(R.properties.y))
|
||||
Assert.IsFalse(KindGuard.IsOptional(R.properties.y))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsArray(R.properties.z))
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.z.items))
|
||||
Assert.IsTrue(KindGuard.IsOptional(R.properties.z))
|
||||
Assert.IsFalse(KindGuard.IsReadonly(R.properties.z))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsArray(R.properties.w))
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.w.items))
|
||||
Assert.IsFalse(KindGuard.IsOptional(R.properties.w))
|
||||
Assert.IsFalse(KindGuard.IsReadonly(R.properties.w))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Modifiers: 3
|
||||
// ----------------------------------------------------------------
|
||||
it('Should compute for Modifiers 3', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({
|
||||
x: Type.Array(Type.Null()),
|
||||
}),
|
||||
// Computed Partial
|
||||
U: Type.Partial(Type.Ref('T')),
|
||||
})
|
||||
const T = Module.Import('U')
|
||||
const R = T.$defs[T.$ref]
|
||||
Assert.IsTrue(KindGuard.IsObject(R))
|
||||
|
||||
Assert.IsTrue(KindGuard.IsArray(R.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsNull(R.properties.x.items))
|
||||
Assert.IsTrue(KindGuard.IsOptional(R.properties.x))
|
||||
})
|
||||
})
|
||||
54
test/runtime/type/guard/kind/index.ts
Normal file
54
test/runtime/type/guard/kind/index.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import './any'
|
||||
import './argument'
|
||||
import './array'
|
||||
import './async-iterator'
|
||||
import './awaited'
|
||||
import './bigint'
|
||||
import './boolean'
|
||||
import './capitalize'
|
||||
import './composite'
|
||||
import './computed'
|
||||
import './const'
|
||||
import './constructor'
|
||||
import './date'
|
||||
import './enum'
|
||||
import './exclude'
|
||||
import './extract'
|
||||
import './function'
|
||||
import './import'
|
||||
import './indexed'
|
||||
import './integer'
|
||||
import './intersect'
|
||||
import './iterator'
|
||||
import './keyof'
|
||||
import './kind'
|
||||
import './literal'
|
||||
import './lowercase'
|
||||
import './mapped'
|
||||
import './not'
|
||||
import './null'
|
||||
import './number'
|
||||
import './object'
|
||||
import './omit'
|
||||
import './partial'
|
||||
import './pick'
|
||||
import './promise'
|
||||
import './record'
|
||||
import './recursive'
|
||||
import './ref'
|
||||
import './regexp'
|
||||
import './required'
|
||||
import './rest'
|
||||
import './string'
|
||||
import './symbol'
|
||||
import './template-literal'
|
||||
import './this'
|
||||
import './tuple'
|
||||
import './uint8array'
|
||||
import './uncapitalize'
|
||||
import './undefined'
|
||||
import './union'
|
||||
import './unknown'
|
||||
import './unsafe'
|
||||
import './uppercase'
|
||||
import './void'
|
||||
327
test/runtime/type/guard/kind/indexed.ts
Normal file
327
test/runtime/type/guard/kind/indexed.ts
Normal file
@@ -0,0 +1,327 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TIndex', () => {
|
||||
it('Should Index 1', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const I = Type.Index(T, ['x'])
|
||||
Assert.IsTrue(KindGuard.IsNumber(I))
|
||||
})
|
||||
it('Should Index 2', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const I = Type.Index(T, ['x', 'y'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 3', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const I = Type.Index(T, Type.KeyOf(T))
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 4', () => {
|
||||
const T = Type.Object({
|
||||
ab: Type.Number(),
|
||||
ac: Type.String(),
|
||||
})
|
||||
const I = Type.Index(T, Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 5', () => {
|
||||
const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.String() })])
|
||||
const I = Type.Index(T, ['x', 'y'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 6', () => {
|
||||
const T = Type.Union([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.String() })])
|
||||
const I = Type.Index(T, ['x'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 7', () => {
|
||||
const T = Type.Array(Type.Null())
|
||||
const I = Type.Index(T, Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsNull(I))
|
||||
})
|
||||
it('Should Index 6', () => {
|
||||
const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')])
|
||||
const I = Type.Index(T, [0])
|
||||
Assert.IsTrue(KindGuard.IsLiteralString(I))
|
||||
Assert.IsEqual(I.const, 'hello')
|
||||
})
|
||||
it('Should Index 8', () => {
|
||||
const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')])
|
||||
const I = Type.Index(T, [1])
|
||||
Assert.IsTrue(KindGuard.IsLiteralString(I))
|
||||
Assert.IsEqual(I.const, 'world')
|
||||
})
|
||||
it('Should Index 9', () => {
|
||||
const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')])
|
||||
const I = Type.Index(T, [0, 1])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsEqual(I.anyOf[0].const, 'hello')
|
||||
Assert.IsEqual(I.anyOf[1].const, 'world')
|
||||
})
|
||||
it('Should Index 10', () => {
|
||||
const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')])
|
||||
const I = Type.Index(T, [1, 0])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsEqual(I.anyOf[0].const, 'world')
|
||||
Assert.IsEqual(I.anyOf[1].const, 'hello')
|
||||
})
|
||||
it('Should Index 11', () => {
|
||||
const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')])
|
||||
const I = Type.Index(T, [0, 0, 0, 1])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsEqual(I.anyOf[0].const, 'hello')
|
||||
Assert.IsEqual(I.anyOf[1].const, 'hello')
|
||||
Assert.IsEqual(I.anyOf[2].const, 'hello')
|
||||
Assert.IsEqual(I.anyOf[3].const, 'world')
|
||||
})
|
||||
it('Should Index 12', () => {
|
||||
const T = Type.Tuple([Type.String(), Type.Boolean()])
|
||||
const I = Type.Index(T, Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsBoolean(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 13', () => {
|
||||
const T = Type.Tuple([Type.String()])
|
||||
const I = Type.Index(T, Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsString(I))
|
||||
})
|
||||
it('Should Index 14', () => {
|
||||
const T = Type.Tuple([])
|
||||
const I = Type.Index(T, Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsNever(I))
|
||||
})
|
||||
it('Should Index 15', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Literal(0))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I))
|
||||
})
|
||||
it('Should Index 16', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Literal('0'))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I))
|
||||
})
|
||||
it('Should Index 17', () => {
|
||||
const T = Type.Object({
|
||||
'0': Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Literal(0))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I))
|
||||
})
|
||||
it('Should Index 18', () => {
|
||||
const T = Type.Object({
|
||||
'0': Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Literal('0'))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I))
|
||||
})
|
||||
it('Should Index 19', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.String(),
|
||||
2: Type.Boolean(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(2)]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsBoolean(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 20', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.String(),
|
||||
2: Type.Boolean(),
|
||||
})
|
||||
const I = Type.Index(T, Type.BigInt())
|
||||
Assert.IsTrue(KindGuard.IsNever(I))
|
||||
})
|
||||
it('Should Index 21', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.String(),
|
||||
2: Type.Boolean(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Object({}))
|
||||
Assert.IsTrue(KindGuard.IsNever(I))
|
||||
})
|
||||
it('Should Index 22', () => {
|
||||
const A = Type.Object({ x: Type.Literal('A') })
|
||||
const B = Type.Object({ x: Type.Literal('B') })
|
||||
const C = Type.Object({ x: Type.Literal('C') })
|
||||
const D = Type.Object({ x: Type.Literal('D') })
|
||||
const T = Type.Intersect([A, B, C, D])
|
||||
const I = Type.Index(T, ['x'])
|
||||
Assert.IsTrue(KindGuard.IsIntersect(I))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.allOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.allOf[1]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.allOf[2]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.allOf[3]))
|
||||
})
|
||||
it('Should Index 23', () => {
|
||||
const A = Type.Object({ x: Type.Literal('A') })
|
||||
const B = Type.Object({ x: Type.Literal('B') })
|
||||
const C = Type.Object({ x: Type.Literal('C') })
|
||||
const D = Type.Object({ x: Type.Literal('D') })
|
||||
const T = Type.Union([A, B, C, D])
|
||||
const I = Type.Index(T, ['x'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[1]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[2]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[3]))
|
||||
})
|
||||
it('Should Index 24', () => {
|
||||
const A = Type.Object({ x: Type.Literal('A'), y: Type.Number() })
|
||||
const B = Type.Object({ x: Type.Literal('B') })
|
||||
const C = Type.Object({ x: Type.Literal('C') })
|
||||
const D = Type.Object({ x: Type.Literal('D') })
|
||||
const T = Type.Intersect([A, B, C, D])
|
||||
const I = Type.Index(T, ['x', 'y'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsIntersect(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 25', () => {
|
||||
const A = Type.Object({ x: Type.Literal('A'), y: Type.Number() })
|
||||
const B = Type.Object({ x: Type.Literal('B'), y: Type.String() })
|
||||
const C = Type.Object({ x: Type.Literal('C') })
|
||||
const D = Type.Object({ x: Type.Literal('D') })
|
||||
const T = Type.Intersect([A, B, C, D])
|
||||
const I = Type.Index(T, ['x', 'y'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsIntersect(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsIntersect(I.anyOf[1]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1].allOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[1].allOf[1]))
|
||||
})
|
||||
it('Should Index 26', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
x: Type.String(),
|
||||
y: Type.Number(),
|
||||
z: This,
|
||||
}),
|
||||
)
|
||||
const I = Type.Index(T, ['x', 'y', 'z'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
Assert.IsTrue(KindGuard.IsThis(I.anyOf[2]))
|
||||
})
|
||||
it('Should Index 27', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.String(),
|
||||
1: Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, [0, 1])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 28', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.String(),
|
||||
'1': Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, [0, '1'])
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 29', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.String(),
|
||||
'1': Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal('1')]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 30', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.String(),
|
||||
'1': Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(1)]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
// Note: Expect TNever for anyOf[1] but permit for TNumber due to IndexedAccess
|
||||
// Resolve() which currently cannot differentiate between string and numeric keys
|
||||
// on the object. This may be resolvable in later revisions, but test for this
|
||||
// fall-through to ensure case is documented. For review.
|
||||
})
|
||||
// --------------------------------------------------------
|
||||
// Modifier Optional Indexing
|
||||
// --------------------------------------------------------
|
||||
it('Should Index 31', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Optional(Type.String()),
|
||||
y: Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, ['x'])
|
||||
Assert.IsTrue(KindGuard.IsOptional(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I))
|
||||
})
|
||||
it('Should Index 32', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Optional(Type.String()),
|
||||
y: Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, ['y'])
|
||||
Assert.IsFalse(KindGuard.IsOptional(I))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I))
|
||||
})
|
||||
it('Should Index 33', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Optional(Type.String()),
|
||||
y: Type.Number(),
|
||||
})
|
||||
const I = Type.Index(T, ['x', 'y'])
|
||||
Assert.IsTrue(KindGuard.IsOptional(I))
|
||||
Assert.IsTrue(KindGuard.IsUnion(I))
|
||||
Assert.IsTrue(KindGuard.IsString(I.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1]))
|
||||
})
|
||||
it('Should Index 34', () => {
|
||||
const T = Type.String()
|
||||
const I = Type.Index(T, ['x'])
|
||||
Assert.IsTrue(KindGuard.IsNever(I))
|
||||
})
|
||||
it('Should Index 35', () => {
|
||||
const T = Type.Array(Type.String())
|
||||
const I = Type.Index(T, Type.Number())
|
||||
Assert.IsTrue(KindGuard.IsString(I))
|
||||
})
|
||||
it('Should Index 36', () => {
|
||||
const T = Type.Array(Type.String())
|
||||
const I = Type.Index(T, ['[number]'])
|
||||
Assert.IsTrue(KindGuard.IsString(I))
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/integer.ts
Normal file
14
test/runtime/type/guard/kind/integer.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TInteger', () => {
|
||||
it('Should guard for TInteger', () => {
|
||||
const R = KindGuard.IsInteger(Type.Integer())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TInteger', () => {
|
||||
const R = KindGuard.IsInteger(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
39
test/runtime/type/guard/kind/intersect.ts
Normal file
39
test/runtime/type/guard/kind/intersect.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TIntersect', () => {
|
||||
it('Should guard for TIntersect', () => {
|
||||
const R = KindGuard.IsIntersect(
|
||||
Type.Intersect([
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TIntersect', () => {
|
||||
const R = KindGuard.IsIntersect(
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should throw for intersected transform types', () => {
|
||||
const N = Type.Transform(Type.Number())
|
||||
.Decode((value) => value)
|
||||
.Encode((value) => value)
|
||||
|
||||
Assert.Throws(() => Type.Intersect([N, N]))
|
||||
})
|
||||
})
|
||||
16
test/runtime/type/guard/kind/iterator.ts
Normal file
16
test/runtime/type/guard/kind/iterator.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TIterator', () => {
|
||||
it('Should guard for TIterator', () => {
|
||||
const T = Type.Iterator(Type.Any())
|
||||
const R = KindGuard.IsIterator(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TIterator', () => {
|
||||
const T = null
|
||||
const R = KindGuard.IsIterator(T)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
76
test/runtime/type/guard/kind/keyof.ts
Normal file
76
test/runtime/type/guard/kind/keyof.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TKeyOf', () => {
|
||||
it('Should KeyOf 1', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsUnion(K))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[1]))
|
||||
})
|
||||
it('Should KeyOf 2', () => {
|
||||
const T = Type.Recursive((Self) =>
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Array(Self),
|
||||
}),
|
||||
)
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsUnion(K))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[1]))
|
||||
})
|
||||
it('Should KeyOf 3', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
])
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsUnion(K))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[1]))
|
||||
})
|
||||
it('Should KeyOf 4', () => {
|
||||
const T = Type.Union([
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
])
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsNever(K))
|
||||
})
|
||||
it('Should KeyOf 5', () => {
|
||||
const T = Type.Null()
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsNever(K))
|
||||
})
|
||||
it('Should KeyOf 6', () => {
|
||||
const T = Type.Array(Type.Number())
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsNumber(K))
|
||||
})
|
||||
it('Should KeyOf 7', () => {
|
||||
const T = Type.Tuple([])
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsNever(K))
|
||||
})
|
||||
it('Should KeyOf 8', () => {
|
||||
const T = Type.Tuple([Type.Number(), Type.Null()])
|
||||
const K = Type.KeyOf(T)
|
||||
Assert.IsTrue(KindGuard.IsUnion(K))
|
||||
Assert.IsEqual(K.anyOf[0].const, '0')
|
||||
Assert.IsEqual(K.anyOf[1].const, '1')
|
||||
})
|
||||
})
|
||||
13
test/runtime/type/guard/kind/kind.ts
Normal file
13
test/runtime/type/guard/kind/kind.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { KindGuard, Kind } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TKind', () => {
|
||||
it('Should guard 1', () => {
|
||||
const T = { [Kind]: 'Kind' }
|
||||
Assert.IsTrue(KindGuard.IsKind(T))
|
||||
})
|
||||
it('Should guard 2', () => {
|
||||
const T = {}
|
||||
Assert.IsFalse(KindGuard.IsKind(T))
|
||||
})
|
||||
})
|
||||
18
test/runtime/type/guard/kind/literal.ts
Normal file
18
test/runtime/type/guard/kind/literal.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TLiteral', () => {
|
||||
it('Should guard for TLiteral of String', () => {
|
||||
const R = KindGuard.IsLiteral(Type.Literal('hello'))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TLiteral of Number', () => {
|
||||
const R = KindGuard.IsLiteral(Type.Literal(42))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TLiteral of Boolean', () => {
|
||||
const R = KindGuard.IsLiteral(Type.Literal(true))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/kind/lowercase.ts
Normal file
33
test/runtime/type/guard/kind/lowercase.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { KindGuard, Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/Lowercase', () => {
|
||||
it('Should guard for Lowercase 1', () => {
|
||||
const T = Type.Lowercase(Type.Literal('HELLO'), { $id: 'hello', foo: 1 })
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
Assert.IsEqual(T.$id, 'hello')
|
||||
Assert.IsEqual(T.foo, 1)
|
||||
})
|
||||
it('Should guard for Lowercase 2', () => {
|
||||
const T = Type.Lowercase(Type.Literal('HELLO'))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should guard for Lowercase 3', () => {
|
||||
const T = Type.Lowercase(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'hello')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'world')
|
||||
})
|
||||
it('Should guard for Lowercase 4', () => {
|
||||
const T = Type.Lowercase(Type.TemplateLiteral('HELLO${0|1}'))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(hello0|hello1)$')
|
||||
})
|
||||
it('Should guard for Lowercase 5', () => {
|
||||
const T = Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(hello0|hello1)$')
|
||||
})
|
||||
})
|
||||
609
test/runtime/type/guard/kind/mapped.ts
Normal file
609
test/runtime/type/guard/kind/mapped.ts
Normal file
@@ -0,0 +1,609 @@
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
// prettier-ignore
|
||||
describe('guard/kind/Mapped', () => {
|
||||
it('Should guard mapped 1', () => {
|
||||
const T = Type.Mapped(Type.Union([
|
||||
Type.Literal('x'),
|
||||
Type.Literal('y'),
|
||||
Type.Literal('z'),
|
||||
]), _ => Type.Number(), { custom: 1 })
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number()
|
||||
}, { custom: 1 }))
|
||||
})
|
||||
it('Should guard mapped 2', () => {
|
||||
const T = Type.Mapped(Type.Union([
|
||||
Type.Literal('x'),
|
||||
Type.Literal('y'),
|
||||
Type.Literal('z'),
|
||||
]), _ => Type.Number())
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number()
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 3', () => {
|
||||
const T = Type.Mapped(Type.Union([
|
||||
Type.Literal('x'),
|
||||
Type.Literal('y'),
|
||||
Type.Literal('z'),
|
||||
]), K => K)
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Literal('x'),
|
||||
y: Type.Literal('y'),
|
||||
z: Type.Literal('z'),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 4', () => {
|
||||
const T = Type.Mapped(Type.TemplateLiteral('${0|1}${0|1}'), K => Type.Number())
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
'00': Type.Number(),
|
||||
'01': Type.Number(),
|
||||
'10': Type.Number(),
|
||||
'11': Type.Number(),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 5', () => {
|
||||
const T = Type.Mapped(Type.TemplateLiteral('${a|b}'), X =>
|
||||
Type.Mapped(Type.TemplateLiteral('${c|d}'), Y =>
|
||||
Type.Mapped(Type.TemplateLiteral('${e|f}'), Z =>
|
||||
Type.Tuple([X, Y, Z])
|
||||
)
|
||||
)
|
||||
)
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
a: Type.Object({
|
||||
c: Type.Object({
|
||||
e: Type.Tuple([Type.Literal("a"), Type.Literal("c"), Type.Literal("e")]),
|
||||
f: Type.Tuple([Type.Literal("a"), Type.Literal("c"), Type.Literal("f")])
|
||||
}),
|
||||
d: Type.Object({
|
||||
e: Type.Tuple([Type.Literal("a"), Type.Literal("d"), Type.Literal("e")]),
|
||||
f: Type.Tuple([Type.Literal("a"), Type.Literal("d"), Type.Literal("f")])
|
||||
}),
|
||||
}),
|
||||
b: Type.Object({
|
||||
c: Type.Object({
|
||||
e: Type.Tuple([Type.Literal("b"), Type.Literal("c"), Type.Literal("e")]),
|
||||
f: Type.Tuple([Type.Literal("b"), Type.Literal("c"), Type.Literal("f")])
|
||||
}),
|
||||
d: Type.Object({
|
||||
e: Type.Tuple([Type.Literal("b"), Type.Literal("d"), Type.Literal("e")]),
|
||||
f: Type.Tuple([Type.Literal("b"), Type.Literal("d"), Type.Literal("f")])
|
||||
}),
|
||||
}),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 6', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
z: Type.Boolean()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => K)
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Literal('x'),
|
||||
y: Type.Literal('y'),
|
||||
z: Type.Literal('z')
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 7', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
z: Type.Boolean()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
z: Type.Boolean()
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 8', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
z: Type.Boolean()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K, { custom: 1 }))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Number({ custom: 1 }),
|
||||
y: Type.String({ custom: 1 }),
|
||||
z: Type.Boolean({ custom: 1 })
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Extract
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 9', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Extract(Type.Index(T, K), Type.String())
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.String()
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 10', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Extract(Type.Index(T, K), Type.Union([
|
||||
Type.String(),
|
||||
Type.Number()
|
||||
]))
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number()])
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 11', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Extract(Type.Index(T, K), Type.Null())
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Never()
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Extends
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 12', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
z: Type.Boolean()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return (
|
||||
Type.Extends(K, Type.Literal('x'), Type.Literal(1),
|
||||
Type.Extends(K, Type.Literal('y'), Type.Literal(2),
|
||||
Type.Extends(K, Type.Literal('z'), Type.Literal(3), Type.Never())))
|
||||
)
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Literal(1),
|
||||
y: Type.Literal(2),
|
||||
z: Type.Literal(3),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 13', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
z: Type.Boolean()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return (
|
||||
Type.Extends(Type.Index(T, K), Type.Number(), Type.Literal(3),
|
||||
Type.Extends(Type.Index(T, K), Type.String(), Type.Literal(2),
|
||||
Type.Extends(Type.Index(T, K), Type.Boolean(), Type.Literal(1), Type.Never())))
|
||||
)
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Literal(3),
|
||||
y: Type.Literal(2),
|
||||
z: Type.Literal(1),
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Exclude
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 14', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Exclude(Type.Index(T, K), Type.String())
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Union([Type.Number(), Type.Boolean()])
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 15', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Exclude(Type.Index(T, K), Type.Union([
|
||||
Type.String(),
|
||||
Type.Number()
|
||||
]))
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Boolean()
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 16', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Exclude(Type.Index(T, K), Type.Null())
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Union([Type.String(), Type.Number(), Type.Boolean()])
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Non-Evaluated
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 17', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Array(Type.Index(T, K)))
|
||||
Assert.IsEqual(M, Type.Object({ x: Type.Array(Type.Number()) }))
|
||||
})
|
||||
it('Should guard mapped 18', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Promise(Type.Index(T, K)))
|
||||
Assert.IsEqual(M, Type.Object({ x: Type.Promise(Type.Number()) }))
|
||||
})
|
||||
it('Should guard mapped 19', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Function([Type.Index(T, K)], Type.Index(T, K)))
|
||||
Assert.IsEqual(M, Type.Object({ x: Type.Function([Type.Number()], Type.Number())}))
|
||||
})
|
||||
it('Should guard mapped 20', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Tuple([Type.Index(T, K), Type.Index(T, K)]))
|
||||
Assert.IsEqual(M, Type.Object({ x: Type.Tuple([Type.Number(), Type.Number()]) }))
|
||||
})
|
||||
it('Should guard mapped 21', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Union([Type.Index(T, K), Type.Index(T, K)]))
|
||||
Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.Number(), Type.Number()]) }))
|
||||
})
|
||||
it('Should guard mapped 22', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Intersect([Type.Index(T, K), Type.Index(T, K)]))
|
||||
Assert.IsEqual(M, Type.Object({ x: Type.Intersect([Type.Number(), Type.Number()]) }))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Numeric Keys
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 23', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.Number(),
|
||||
2: Type.Number()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => K)
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
0: Type.Literal('0'),
|
||||
1: Type.Literal('1'),
|
||||
2: Type.Literal('2'),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 24', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.Number(),
|
||||
2: Type.Number()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.Number(),
|
||||
2: Type.Number(),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 25', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.Number(),
|
||||
2: Type.Number()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.String())
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
0: Type.String(),
|
||||
1: Type.String(),
|
||||
2: Type.String(),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 26', () => {
|
||||
const T = Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.Number(),
|
||||
2: Type.Number()
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Extends(K, Type.Literal('1'), Type.String(), Type.Number()))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
0: Type.Number(),
|
||||
1: Type.String(),
|
||||
2: Type.Number(),
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Modifiers: Optional
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 27', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Number()
|
||||
})
|
||||
// subtractive
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), false))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number()
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 28', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Number()
|
||||
})
|
||||
// additive
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), true))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number())
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Modifiers: Readonly
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 27', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Readonly(Type.Number()),
|
||||
y: Type.Number()
|
||||
})
|
||||
// subtractive
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), false))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number()
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 28', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Readonly(Type.Number()),
|
||||
y: Type.Number()
|
||||
})
|
||||
// additive
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), true))
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Readonly(Type.Number()),
|
||||
y: Type.Readonly(Type.Number())
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Finite Boolean
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 29', () => {
|
||||
const T = Type.TemplateLiteral('${boolean}')
|
||||
const M = Type.Mapped(T, K => K)
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
true: Type.Literal('true'),
|
||||
false: Type.Literal('false'),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 30', () => {
|
||||
const T = Type.TemplateLiteral('${0|1}${boolean}')
|
||||
const M = Type.Mapped(T, K => K)
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
'0true': Type.Literal('0true'),
|
||||
'0false': Type.Literal('0false'),
|
||||
'1true': Type.Literal('1true'),
|
||||
'1false': Type.Literal('1false'),
|
||||
}))
|
||||
})
|
||||
it('Should guard mapped 31', () => {
|
||||
const T = Type.TemplateLiteral('${boolean}${0|1}')
|
||||
const M = Type.Mapped(T, K => K)
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
'true0': Type.Literal('true0'),
|
||||
'true1': Type.Literal('true1'),
|
||||
'false0': Type.Literal('false0'),
|
||||
'false1': Type.Literal('false1'),
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Numeric Mapping
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 32', () => {
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Union([Type.Literal(0), Type.Literal(1)]),
|
||||
Type.Union([Type.Literal(0), Type.Literal(1)]),
|
||||
])
|
||||
const M = Type.Mapped(T, (K) => K)
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
'00': Type.Literal('00'),
|
||||
'01': Type.Literal('01'),
|
||||
'10': Type.Literal('10'),
|
||||
'11': Type.Literal('11'),
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Indexed Key Remap
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 33', () => {
|
||||
const T = Type.Object({
|
||||
hello: Type.Number(),
|
||||
world: Type.String(),
|
||||
})
|
||||
const M = Type.Mapped(Type.Uppercase(Type.KeyOf(T)), (K) => {
|
||||
return Type.Index(T, Type.Lowercase(K))
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
HELLO: Type.Number(),
|
||||
WORLD: Type.String()
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Partial
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 34', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), (K) => {
|
||||
return Type.Partial(Type.Index(T, K))
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Partial(Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number()),
|
||||
})),
|
||||
y: Type.Partial(Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number()),
|
||||
})),
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Required
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard mapped 35', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Partial(Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})),
|
||||
y: Type.Partial(Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})),
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), (K) => {
|
||||
return Type.Required(Type.Index(T, K))
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
}))
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Pick With Key
|
||||
// ------------------------------------------------------------------
|
||||
it('Should guard mapped 36', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number()
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number()
|
||||
})
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Pick(T, K)
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})
|
||||
}),
|
||||
y: Type.Object({
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})
|
||||
}),
|
||||
}))
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Pick With Result
|
||||
// ------------------------------------------------------------------
|
||||
it('Should guard mapped 37', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), (K) => {
|
||||
return Type.Pick(Type.Index(T, K), ['x'])
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Object({ x: Type.Number() }),
|
||||
y: Type.Object({ x: Type.Number() })
|
||||
}))
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Omit With Key
|
||||
// ------------------------------------------------------------------
|
||||
it('Should guard mapped 36', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number()
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number()
|
||||
})
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), K => {
|
||||
return Type.Omit(T, K)
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})
|
||||
}),
|
||||
}))
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Omit With Result
|
||||
// ------------------------------------------------------------------
|
||||
it('Should guard mapped 37', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
y: Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const M = Type.Mapped(Type.KeyOf(T), (K) => {
|
||||
return Type.Omit(Type.Index(T, K), ['x'])
|
||||
})
|
||||
Assert.IsEqual(M, Type.Object({
|
||||
x: Type.Object({ y: Type.Number() }),
|
||||
y: Type.Object({ y: Type.Number() })
|
||||
}))
|
||||
})
|
||||
})
|
||||
10
test/runtime/type/guard/kind/not.ts
Normal file
10
test/runtime/type/guard/kind/not.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TNot', () => {
|
||||
it('Should guard for TNot', () => {
|
||||
const R = KindGuard.IsNot(Type.Not(Type.String()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/null.ts
Normal file
14
test/runtime/type/guard/kind/null.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TNull', () => {
|
||||
it('Should guard for TNull', () => {
|
||||
const R = KindGuard.IsNull(Type.Null())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TNull', () => {
|
||||
const R = KindGuard.IsNull(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/number.ts
Normal file
14
test/runtime/type/guard/kind/number.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TNumber', () => {
|
||||
it('Should guard for TNumber', () => {
|
||||
const R = KindGuard.IsNumber(Type.Number())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TNumber', () => {
|
||||
const R = KindGuard.IsNumber(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
19
test/runtime/type/guard/kind/object.ts
Normal file
19
test/runtime/type/guard/kind/object.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TObject', () => {
|
||||
it('Should guard for TObject', () => {
|
||||
const R = KindGuard.IsObject(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TObject', () => {
|
||||
const R = KindGuard.IsObject(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
129
test/runtime/type/guard/kind/omit.ts
Normal file
129
test/runtime/type/guard/kind/omit.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { KindGuard, Type, Kind, TransformKind } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TOmit', () => {
|
||||
// -------------------------------------------------------------------------
|
||||
// case: https://github.com/sinclairzx81/typebox/issues/384
|
||||
// -------------------------------------------------------------------------
|
||||
it('Should support TUnsafe omit properties with no Kind', () => {
|
||||
const T = Type.Omit(Type.Object({ x: Type.Unsafe({ x: 1 }), y: Type.Number() }), ['x'])
|
||||
Assert.IsEqual(T.required, ['y'])
|
||||
})
|
||||
it('Should support TUnsafe omit properties with unregistered Kind', () => {
|
||||
const T = Type.Omit(Type.Object({ x: Type.Unsafe({ x: 1, [Kind]: 'UnknownOmitType' }), y: Type.Number() }), ['x'])
|
||||
Assert.IsEqual(T.required, ['y'])
|
||||
})
|
||||
// -------------------------------------------------------------------------
|
||||
// Standard Tests
|
||||
// -------------------------------------------------------------------------
|
||||
it('Should Omit 1', () => {
|
||||
const T = Type.Omit(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
['x'],
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.y))
|
||||
Assert.IsEqual(T.required, ['y'])
|
||||
})
|
||||
it('Should Omit 2', () => {
|
||||
const T = Type.Omit(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Optional(Type.Number()),
|
||||
}),
|
||||
['x'],
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.y))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should Omit 3', () => {
|
||||
const L = Type.Literal('x')
|
||||
const T = Type.Omit(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.y))
|
||||
Assert.IsEqual(T.required, ['y'])
|
||||
})
|
||||
it('Should Omit 4', () => {
|
||||
const L = Type.Literal('x')
|
||||
const T = Type.Omit(Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]), L)
|
||||
Assert.IsEqual(KindGuard.IsNumber(T.allOf[1].properties.y), true)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.allOf[1].properties.x, undefined)
|
||||
})
|
||||
it('Should Omit 5', () => {
|
||||
const L = Type.Union([Type.Literal('x'), Type.Literal('y')])
|
||||
const T = Type.Omit(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.properties.x, undefined)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.properties.y, undefined)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should Omit 6', () => {
|
||||
const L = Type.Union([Type.Literal('x'), Type.Literal('y'), Type.Literal('z')])
|
||||
const T = Type.Omit(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.properties.x, undefined)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.properties.y, undefined)
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should Omit 7', () => {
|
||||
const L = Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])])
|
||||
const T = Type.Omit(
|
||||
Type.Object({
|
||||
ab: Type.Number(),
|
||||
ac: Type.Number(),
|
||||
ad: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.ad))
|
||||
Assert.IsEqual(T.required, ['ad'])
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should override $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Omit(A, ['x'], { $id: 'T' })
|
||||
Assert.IsEqual(T.$id!, 'T')
|
||||
})
|
||||
it('Should discard $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Omit(A, ['x'])
|
||||
Assert.IsFalse('$id' in T)
|
||||
})
|
||||
it('Should discard transform', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const S = Type.Transform(T)
|
||||
.Decode((value) => value)
|
||||
.Encode((value) => value)
|
||||
const R = Type.Omit(S, ['x'])
|
||||
Assert.IsFalse(TransformKind in R)
|
||||
})
|
||||
})
|
||||
99
test/runtime/type/guard/kind/partial.ts
Normal file
99
test/runtime/type/guard/kind/partial.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { KindGuard, TypeRegistry, Type, Kind, TransformKind } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TPartial', () => {
|
||||
it('Should produce a valid TSchema', () => {
|
||||
const T = Type.Partial(Type.Object({ x: Type.Number() }))
|
||||
Assert.IsTrue(KindGuard.IsSchema(T))
|
||||
})
|
||||
// -------------------------------------------------------------------------
|
||||
// case: https://github.com/sinclairzx81/typebox/issues/364
|
||||
// -------------------------------------------------------------------------
|
||||
it('Should support TUnsafe partial properties with no Kind', () => {
|
||||
const T = Type.Partial(Type.Object({ x: Type.Unsafe({ x: 1 }) }))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should support TUnsafe partial properties with unknown Kind', () => {
|
||||
const T = Type.Partial(Type.Object({ x: Type.Unsafe({ [Kind]: 'UnknownPartialType', x: 1 }) }))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should support TUnsafe partial properties with known Kind', () => {
|
||||
TypeRegistry.Set('KnownPartialType', () => true)
|
||||
const T = Type.Partial(Type.Object({ x: Type.Unsafe({ [Kind]: 'KnownPartialType', x: 1 }) }))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should support applying partial to intersect', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const I = Type.Intersect([A, B])
|
||||
const T = Type.Partial(I)
|
||||
Assert.IsEqual(T.allOf.length, 2)
|
||||
Assert.IsEqual(T.allOf[0].required, undefined)
|
||||
Assert.IsEqual(T.allOf[1].required, undefined)
|
||||
})
|
||||
it('Should support applying partial to union', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const I = Type.Union([A, B])
|
||||
const T = Type.Partial(I)
|
||||
Assert.IsEqual(T.anyOf.length, 2)
|
||||
Assert.IsEqual(T.anyOf[0].required, undefined)
|
||||
Assert.IsEqual(T.anyOf[1].required, undefined)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should override $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Partial(A, { $id: 'T' })
|
||||
Assert.IsEqual(T.$id!, 'T')
|
||||
})
|
||||
it('Should discard $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Partial(A)
|
||||
Assert.IsFalse('$id' in T)
|
||||
})
|
||||
it('Should discard transform', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const S = Type.Transform(T)
|
||||
.Decode((value) => value)
|
||||
.Encode((value) => value)
|
||||
const R = Type.Partial(S)
|
||||
Assert.IsFalse(TransformKind in R)
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Intrinsic Passthough
|
||||
// https://github.com/sinclairzx81/typebox/issues/1169
|
||||
// ------------------------------------------------------------------
|
||||
it('Should pass through on intrinsic types on union 1', () => {
|
||||
const T = Type.Partial(
|
||||
Type.Union([
|
||||
Type.Number(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
|
||||
Assert.IsTrue(KindGuard.IsOptional(T.anyOf[1].properties.x))
|
||||
})
|
||||
it('Should pass through on intrinsic types on union 2', () => {
|
||||
const T = Type.Partial(
|
||||
Type.Union([
|
||||
Type.Literal(1),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
|
||||
Assert.IsTrue(KindGuard.IsOptional(T.anyOf[1].properties.x))
|
||||
})
|
||||
})
|
||||
131
test/runtime/type/guard/kind/pick.ts
Normal file
131
test/runtime/type/guard/kind/pick.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { KindGuard, Type, Kind, TransformKind } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TPick', () => {
|
||||
// -------------------------------------------------------------------------
|
||||
// case: https://github.com/sinclairzx81/typebox/issues/384
|
||||
// -------------------------------------------------------------------------
|
||||
it('Should support TUnsafe omit properties with no Kind', () => {
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
x: Type.Unsafe({ x: 1 }),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
['x'],
|
||||
)
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
it('Should support TUnsafe omit properties with unregistered Kind', () => {
|
||||
const T = Type.Pick(Type.Object({ x: Type.Unsafe({ x: 1, [Kind]: 'UnknownPickType' }), y: Type.Number() }), ['x'])
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
// -------------------------------------------------------------------------
|
||||
// Standard Tests
|
||||
// -------------------------------------------------------------------------
|
||||
it('Should Pick 1', () => {
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
['x'],
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x))
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
it('Should Pick 2', () => {
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
['x'],
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
it('Should Pick 3', () => {
|
||||
const L = Type.Literal('x')
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x))
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
it('Should Pick 4', () => {
|
||||
const L = Type.Literal('x')
|
||||
const T = Type.Pick(Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]), L)
|
||||
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.allOf[0].properties.x))
|
||||
// @ts-ignore
|
||||
Assert.IsEqual(T.allOf[1].properties.y, undefined)
|
||||
})
|
||||
it('Should Pick 5', () => {
|
||||
const L = Type.Union([Type.Literal('x'), Type.Literal('y')])
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.y))
|
||||
Assert.IsEqual(T.required, ['x', 'y'])
|
||||
})
|
||||
it('Should Pick 6', () => {
|
||||
const L = Type.Union([Type.Literal('x'), Type.Literal('y'), Type.Literal('z')])
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.y))
|
||||
Assert.IsEqual(T.required, ['x', 'y'])
|
||||
})
|
||||
it('Should Pick 7', () => {
|
||||
const L = Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])])
|
||||
const T = Type.Pick(
|
||||
Type.Object({
|
||||
ab: Type.Number(),
|
||||
ac: Type.Number(),
|
||||
ad: Type.Number(),
|
||||
}),
|
||||
L,
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.ab))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.properties.ac))
|
||||
Assert.IsEqual(T.required, ['ab', 'ac'])
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should override $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Pick(A, ['x'], { $id: 'T' })
|
||||
Assert.IsEqual(T.$id!, 'T')
|
||||
})
|
||||
it('Should discard $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Pick(A, ['x'])
|
||||
Assert.IsFalse('$id' in T)
|
||||
})
|
||||
it('Should discard transform', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const S = Type.Transform(T)
|
||||
.Decode((value) => value)
|
||||
.Encode((value) => value)
|
||||
const R = Type.Pick(S, ['x'])
|
||||
Assert.IsFalse(TransformKind in R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/promise.ts
Normal file
14
test/runtime/type/guard/kind/promise.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TPromise', () => {
|
||||
it('Should guard for TPromise', () => {
|
||||
const R = KindGuard.IsPromise(Type.Promise(Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TPromise', () => {
|
||||
const R = KindGuard.IsPromise(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
176
test/runtime/type/guard/kind/record.ts
Normal file
176
test/runtime/type/guard/kind/record.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import { TypeGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNeverExact } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TRecord', () => {
|
||||
// -------------------------------------------------------------
|
||||
// Overloads
|
||||
// -------------------------------------------------------------
|
||||
it('Should guard overload 1', () => {
|
||||
const T = Type.Record(Type.Union([Type.Literal('A'), Type.Literal('B')]), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.A))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.B))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 2', () => {
|
||||
const T = Type.Record(Type.Union([Type.Literal('A')]), Type.String(), { extra: 1 }) // unwrap as literal
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.A))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 3', () => {
|
||||
// @ts-ignore
|
||||
const N = Type.Union([]) // Never
|
||||
const T = Type.Record(N, Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNeverExact]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 4', () => {
|
||||
// @ts-ignore
|
||||
const T = Type.Record(Type.BigInt(), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard overload 5', () => {
|
||||
const T = Type.Record(Type.Literal('A'), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.A))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 6', () => {
|
||||
const L = Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal('A'), Type.Literal('B')])])
|
||||
const T = Type.Record(L, Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.helloA))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.helloB))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 7', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNumberExact]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 8', () => {
|
||||
const T = Type.Record(Type.Integer(), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNumberExact]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 9', () => {
|
||||
const T = Type.Record(Type.String(), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternStringExact]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 10', () => {
|
||||
const L = Type.TemplateLiteral([Type.String(), Type.Literal('_foo')])
|
||||
const T = Type.Record(L, Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[`^${PatternString}_foo$`]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 11', () => {
|
||||
const L = Type.Union([Type.Literal('A'), Type.Union([Type.Literal('B'), Type.Literal('C')])])
|
||||
const T = Type.Record(L, Type.String())
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.A))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.B))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.C))
|
||||
})
|
||||
it('Should guard overload 12', () => {
|
||||
enum E {
|
||||
A = 'X',
|
||||
B = 'Y',
|
||||
C = 'Z',
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
const R = Type.Record(T, Type.Null())
|
||||
Assert.IsTrue(TypeGuard.IsObject(R))
|
||||
Assert.IsTrue(TypeGuard.IsNull(R.properties.X))
|
||||
Assert.IsTrue(TypeGuard.IsNull(R.properties.Y))
|
||||
Assert.IsTrue(TypeGuard.IsNull(R.properties.Z))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard overload 13', () => {
|
||||
// @ts-ignore
|
||||
const T = Type.Record(Type.Never(), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNeverExact]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
it('Should guard overload 14', () => {
|
||||
// @ts-ignore
|
||||
const T = Type.Record(Type.Any(), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternStringExact]))
|
||||
Assert.IsEqual(T.extra, 1)
|
||||
})
|
||||
// -------------------------------------------------------------
|
||||
// Variants
|
||||
// -------------------------------------------------------------
|
||||
it('Should guard for TRecord', () => {
|
||||
const R = TypeGuard.IsRecord(Type.Record(Type.String(), Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TRecord with TObject value', () => {
|
||||
const R = TypeGuard.IsRecord(
|
||||
Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TRecord', () => {
|
||||
const R = TypeGuard.IsRecord(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TRecord with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsRecord(Type.Record(Type.String(), Type.Number(), { $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TRecord with TObject value with invalid Property', () => {
|
||||
const R = TypeGuard.IsRecord(
|
||||
Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: {} as any,
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Normalize: Should should normalize to TObject for single literal union value', () => {
|
||||
const K = Type.Union([Type.Literal('ok')])
|
||||
const R = TypeGuard.IsObject(Type.Record(K, Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Normalize: Should should normalize to TObject for multi literal union value', () => {
|
||||
const K = Type.Union([Type.Literal('A'), Type.Literal('B')])
|
||||
const R = TypeGuard.IsObject(Type.Record(K, Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Evaluated: Dollar Sign Escape
|
||||
// https://github.com/sinclairzx81/typebox/issues/794
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
{
|
||||
const K = Type.TemplateLiteral('$prop${A|B|C}') // issue
|
||||
const T = Type.Record(K, Type.String())
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.$propA))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.$propB))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.$propC))
|
||||
Assert.IsEqual(T.required, ['$propA', '$propB', '$propC'])
|
||||
}
|
||||
})
|
||||
16
test/runtime/type/guard/kind/recursive.ts
Normal file
16
test/runtime/type/guard/kind/recursive.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { KindGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNumber } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TRecursive', () => {
|
||||
it('Should guard 1', () => {
|
||||
const T = Type.Recursive((This) => Type.Object({ nodes: This }))
|
||||
Assert.IsTrue(KindGuard.IsRecursive(T))
|
||||
Assert.IsTrue(KindGuard.IsObject(T))
|
||||
})
|
||||
it('Should guard 2', () => {
|
||||
const T = Type.Recursive((This) => Type.Tuple([This]))
|
||||
Assert.IsTrue(KindGuard.IsRecursive(T))
|
||||
Assert.IsTrue(KindGuard.IsTuple(T))
|
||||
})
|
||||
})
|
||||
36
test/runtime/type/guard/kind/ref.ts
Normal file
36
test/runtime/type/guard/kind/ref.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TRef', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Deprecated
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Ref(Schema) 1', () => {
|
||||
const T = Type.Number({ $id: 'T' })
|
||||
const R = Type.Ref(T)
|
||||
Assert.IsTrue(KindGuard.IsRef(R))
|
||||
Assert.IsTrue(typeof R['$ref'] === 'string')
|
||||
})
|
||||
it('Should guard for Ref(Schema) 2', () => {
|
||||
const T = Type.Number()
|
||||
Assert.Throws(() => Type.Ref(T))
|
||||
})
|
||||
it('Should guard for Ref(Schema) 3', () => {
|
||||
// @ts-ignore
|
||||
const T = Type.Number({ $id: null })
|
||||
Assert.Throws(() => Type.Ref(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Standard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TRef', () => {
|
||||
const T = Type.Number({ $id: 'T' })
|
||||
const R = KindGuard.IsRef(Type.Ref(T))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TRef', () => {
|
||||
const R = KindGuard.IsRef(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
18
test/runtime/type/guard/kind/regexp.ts
Normal file
18
test/runtime/type/guard/kind/regexp.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TRegExp', () => {
|
||||
it('Should guard for TRegExp 1', () => {
|
||||
const T = Type.RegExp(/foo/, { $id: 'T' })
|
||||
Assert.IsTrue(KindGuard.IsSchema(T))
|
||||
})
|
||||
it('Should guard for TRegExp 1', () => {
|
||||
const T = Type.RegExp(/foo/, { $id: 'T' })
|
||||
Assert.IsTrue(KindGuard.IsRegExp(T))
|
||||
})
|
||||
it('Should guard for TRegExp 2', () => {
|
||||
const T = Type.RegExp('foo', { $id: 'T' })
|
||||
Assert.IsTrue(KindGuard.IsRegExp(T))
|
||||
})
|
||||
})
|
||||
96
test/runtime/type/guard/kind/required.ts
Normal file
96
test/runtime/type/guard/kind/required.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { KindGuard, TypeRegistry, Type, Kind, TransformKind } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TRequired', () => {
|
||||
it('Should produce a valid TSchema', () => {
|
||||
const T = Type.Required(Type.Object({ x: Type.Number() }))
|
||||
Assert.IsTrue(KindGuard.IsSchema(T))
|
||||
})
|
||||
it('Should support TUnsafe required properties with no Kind', () => {
|
||||
const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ x: 1 })) }))
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
it('Should support TUnsafe required properties with unknown Kind', () => {
|
||||
const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ [Kind]: 'UnknownRequiredType', x: 1 })) }))
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
it('Should support TUnsafe required properties with known Kind', () => {
|
||||
TypeRegistry.Set('KnownRequiredType', () => true)
|
||||
const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ [Kind]: 'KnownRequiredType', x: 1 })) }))
|
||||
Assert.IsEqual(T.required, ['x'])
|
||||
})
|
||||
it('Should support applying required to intersect', () => {
|
||||
const A = Type.Object({ x: Type.Optional(Type.Number()) })
|
||||
const B = Type.Object({ y: Type.Optional(Type.Number()) })
|
||||
const I = Type.Intersect([A, B])
|
||||
const T = Type.Required(I)
|
||||
Assert.IsEqual(T.allOf.length, 2)
|
||||
Assert.IsEqual(T.allOf[0].required, ['x'])
|
||||
Assert.IsEqual(T.allOf[1].required, ['y'])
|
||||
})
|
||||
it('Should support applying required to union', () => {
|
||||
const A = Type.Object({ x: Type.Optional(Type.Number()) })
|
||||
const B = Type.Object({ y: Type.Optional(Type.Number()) })
|
||||
const I = Type.Union([A, B])
|
||||
const T = Type.Required(I)
|
||||
Assert.IsEqual(T.anyOf.length, 2)
|
||||
Assert.IsEqual(T.anyOf[0].required, ['x'])
|
||||
Assert.IsEqual(T.anyOf[1].required, ['y'])
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should override $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Required(A, { $id: 'T' })
|
||||
Assert.IsEqual(T.$id!, 'T')
|
||||
})
|
||||
it('Should discard $id', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { $id: 'A' })
|
||||
const T = Type.Required(A)
|
||||
Assert.IsFalse('$id' in T)
|
||||
})
|
||||
it('Should discard transform', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.String(),
|
||||
})
|
||||
const S = Type.Transform(T)
|
||||
.Decode((value) => value)
|
||||
.Encode((value) => value)
|
||||
const R = Type.Required(S)
|
||||
Assert.IsFalse(TransformKind in R)
|
||||
})
|
||||
// ------------------------------------------------------------------
|
||||
// Intrinsic Passthough
|
||||
// https://github.com/sinclairzx81/typebox/issues/1169
|
||||
// ------------------------------------------------------------------
|
||||
it('Should pass through on intrinsic types on union 1', () => {
|
||||
const T = Type.Required(
|
||||
Type.Union([
|
||||
Type.Number(),
|
||||
Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
|
||||
Assert.IsFalse(KindGuard.IsOptional(T.anyOf[1].properties.x))
|
||||
})
|
||||
it('Should pass through on intrinsic types on union 2', () => {
|
||||
const T = Type.Required(
|
||||
Type.Union([
|
||||
Type.Literal(1),
|
||||
Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
|
||||
Assert.IsFalse(KindGuard.IsOptional(T.anyOf[1].properties.x))
|
||||
})
|
||||
})
|
||||
59
test/runtime/type/guard/kind/rest.ts
Normal file
59
test/runtime/type/guard/kind/rest.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Type, KindGuard } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TRest', () => {
|
||||
it('Should guard 1', () => {
|
||||
// union never
|
||||
const A = Type.String()
|
||||
const B = Type.Union(Type.Rest(A))
|
||||
Assert.IsTrue(KindGuard.IsNever(B))
|
||||
})
|
||||
it('Should guard 2', () => {
|
||||
// intersect never
|
||||
const A = Type.String()
|
||||
const B = Type.Intersect(Type.Rest(A))
|
||||
Assert.IsTrue(KindGuard.IsNever(B))
|
||||
})
|
||||
it('Should guard 3', () => {
|
||||
// tuple
|
||||
const A = Type.Tuple([Type.Number(), Type.String()])
|
||||
const B = Type.Union(Type.Rest(A))
|
||||
Assert.IsTrue(KindGuard.IsUnion(B))
|
||||
Assert.IsEqual(B.anyOf.length, 2)
|
||||
Assert.IsTrue(KindGuard.IsNumber(B.anyOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsString(B.anyOf[1]))
|
||||
})
|
||||
it('Should guard 4', () => {
|
||||
// tuple spread
|
||||
const A = Type.Tuple([Type.Literal(1), Type.Literal(2)])
|
||||
const B = Type.Tuple([Type.Literal(3), Type.Literal(4)])
|
||||
const C = Type.Tuple([...Type.Rest(A), ...Type.Rest(B)])
|
||||
Assert.IsTrue(KindGuard.IsTuple(C))
|
||||
Assert.IsEqual(C.items!.length, 4)
|
||||
Assert.IsEqual(C.items![0].const, 1)
|
||||
Assert.IsEqual(C.items![1].const, 2)
|
||||
Assert.IsEqual(C.items![2].const, 3)
|
||||
Assert.IsEqual(C.items![3].const, 4)
|
||||
})
|
||||
it('Should guard 5', () => {
|
||||
// union to intersect
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.String() })
|
||||
const C = Type.Union([A, B])
|
||||
const D = Type.Intersect(Type.Rest(C))
|
||||
Assert.IsTrue(KindGuard.IsIntersect(D))
|
||||
Assert.IsEqual(D.allOf.length, 2)
|
||||
Assert.IsTrue(KindGuard.IsObject(D.allOf[0]))
|
||||
Assert.IsTrue(KindGuard.IsObject(D.allOf[1]))
|
||||
})
|
||||
it('Should guard 6', () => {
|
||||
// intersect to composite
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.String() })
|
||||
const C = Type.Intersect([A, B])
|
||||
const D = Type.Composite(Type.Rest(C))
|
||||
Assert.IsTrue(KindGuard.IsObject(D))
|
||||
Assert.IsTrue(KindGuard.IsNumber(D.properties.x))
|
||||
Assert.IsTrue(KindGuard.IsString(D.properties.y))
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/string.ts
Normal file
14
test/runtime/type/guard/kind/string.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TString', () => {
|
||||
it('Should guard for TString', () => {
|
||||
const R = KindGuard.IsString(Type.String())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TString', () => {
|
||||
const R = KindGuard.IsString(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/symbol.ts
Normal file
14
test/runtime/type/guard/kind/symbol.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TSymbol', () => {
|
||||
it('Should guard for TSymbol', () => {
|
||||
const R = KindGuard.IsSymbol(Type.Symbol())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TSymbol', () => {
|
||||
const R = KindGuard.IsSymbol(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
35
test/runtime/type/guard/kind/template-literal.ts
Normal file
35
test/runtime/type/guard/kind/template-literal.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TTemplateLiteral', () => {
|
||||
it('Should guard for empty TemplateLiteral', () => {
|
||||
const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TSchema', () => {
|
||||
const R = KindGuard.IsSchema(Type.TemplateLiteral([]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TemplateLiteral (TTemplateLiteral)', () => {
|
||||
const T = Type.TemplateLiteral([Type.Literal('hello')])
|
||||
const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([T, Type.Literal('world')]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TemplateLiteral (TLiteral)', () => {
|
||||
const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Literal('hello')]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TemplateLiteral (TString)', () => {
|
||||
const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.String()]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TemplateLiteral (TNumber)', () => {
|
||||
const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Number()]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TemplateLiteral (TBoolean)', () => {
|
||||
const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Boolean()]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
})
|
||||
13
test/runtime/type/guard/kind/this.ts
Normal file
13
test/runtime/type/guard/kind/this.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TThis', () => {
|
||||
it('Should guard for TThis', () => {
|
||||
Type.Recursive((This) => {
|
||||
const R = KindGuard.IsThis(This)
|
||||
Assert.IsTrue(R)
|
||||
return Type.Object({ nodes: Type.Array(This) })
|
||||
})
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/tuple.ts
Normal file
14
test/runtime/type/guard/kind/tuple.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TTuple', () => {
|
||||
it('Should guard for TTuple', () => {
|
||||
const R = KindGuard.IsTuple(Type.Tuple([Type.Number(), Type.Number()]))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TTuple', () => {
|
||||
const R = KindGuard.IsTuple(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/uint8array.ts
Normal file
14
test/runtime/type/guard/kind/uint8array.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TUint8Array', () => {
|
||||
it('Should guard for TUint8Array', () => {
|
||||
const R = KindGuard.IsUint8Array(Type.Uint8Array())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TUint8Array', () => {
|
||||
const R = KindGuard.IsUint8Array(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/kind/uncapitalize.ts
Normal file
33
test/runtime/type/guard/kind/uncapitalize.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { KindGuard, Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/Uncapitalize', () => {
|
||||
it('Should guard for Uncapitalize 1', () => {
|
||||
const T = Type.Uncapitalize(Type.Literal('HELLO'), { $id: 'hello', foo: 1 })
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hELLO')
|
||||
Assert.IsEqual(T.$id, 'hello')
|
||||
Assert.IsEqual(T.foo, 1)
|
||||
})
|
||||
it('Should guard for Uncapitalize 2', () => {
|
||||
const T = Type.Uncapitalize(Type.Literal('HELLO'))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hELLO')
|
||||
})
|
||||
it('Should guard for Uncapitalize 3', () => {
|
||||
const T = Type.Uncapitalize(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'hELLO')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'wORLD')
|
||||
})
|
||||
it('Should guard for Uncapitalize 4', () => {
|
||||
const T = Type.Uncapitalize(Type.TemplateLiteral('HELLO${0|1}'))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$')
|
||||
})
|
||||
it('Should guard for Uncapitalize 5', () => {
|
||||
const T = Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$')
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/undefined.ts
Normal file
14
test/runtime/type/guard/kind/undefined.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TUndefined', () => {
|
||||
it('Should guard for TUndefined', () => {
|
||||
const R = KindGuard.IsUndefined(Type.Undefined())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TUndefined', () => {
|
||||
const R = KindGuard.IsUndefined(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
42
test/runtime/type/guard/kind/union.ts
Normal file
42
test/runtime/type/guard/kind/union.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { TSchema, KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TUnion', () => {
|
||||
it('Should guard for TUnion', () => {
|
||||
const R = KindGuard.IsUnion(
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
}),
|
||||
Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TUnion', () => {
|
||||
const R = KindGuard.IsUnion(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Transform: Should transform to never for zero length union', () => {
|
||||
const T = Type.Union([])
|
||||
const R = KindGuard.IsNever(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Transform: Should unwrap union type for array of length === 1', () => {
|
||||
const T = Type.Union([Type.String()])
|
||||
const R = KindGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Transform: Should retain union if array length > 1', () => {
|
||||
const T = Type.Union([Type.String(), Type.Number()])
|
||||
const R1 = KindGuard.IsUnion(T)
|
||||
const R2 = KindGuard.IsString(T.anyOf[0])
|
||||
const R3 = KindGuard.IsNumber(T.anyOf[1])
|
||||
Assert.IsTrue(R1)
|
||||
Assert.IsTrue(R2)
|
||||
Assert.IsTrue(R3)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/unknown.ts
Normal file
14
test/runtime/type/guard/kind/unknown.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TUnknown', () => {
|
||||
it('Should guard for TUnknown', () => {
|
||||
const R = KindGuard.IsUnknown(Type.Unknown())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TUnknown', () => {
|
||||
const R = KindGuard.IsUnknown(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/kind/unsafe.ts
Normal file
33
test/runtime/type/guard/kind/unsafe.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Kind, KindGuard, TypeRegistry } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TUnsafe', () => {
|
||||
it('Should guard raw TUnsafe', () => {
|
||||
const T = Type.Unsafe({ x: 1 })
|
||||
const R = KindGuard.IsUnsafe(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard raw TUnsafe as TSchema', () => {
|
||||
const T = Type.Unsafe({ x: 1 })
|
||||
const R = KindGuard.IsSchema(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard override TUnsafe as TSchema when registered', () => {
|
||||
TypeRegistry.Set('UnsafeType', () => true)
|
||||
const T = Type.Unsafe({ [Kind]: 'UnsafeType' })
|
||||
const R = KindGuard.IsSchema(T)
|
||||
Assert.IsTrue(R)
|
||||
TypeRegistry.Delete('UnsafeType')
|
||||
})
|
||||
it('Should not guard TUnsafe with unregistered kind', () => {
|
||||
const T = Type.Unsafe({ [Kind]: 'UnsafeType' })
|
||||
const R = KindGuard.IsUnsafe(T)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TString', () => {
|
||||
const T = Type.String()
|
||||
const R = KindGuard.IsUnsafe(T)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/kind/uppercase.ts
Normal file
33
test/runtime/type/guard/kind/uppercase.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { KindGuard, Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/Uppercase', () => {
|
||||
it('Should guard for Uppercase 1', () => {
|
||||
const T = Type.Uppercase(Type.Literal('hello'), { $id: 'hello', foo: 1 })
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'HELLO')
|
||||
Assert.IsEqual(T.$id, 'hello')
|
||||
Assert.IsEqual(T.foo, 1)
|
||||
})
|
||||
it('Should guard for Uppercase 2', () => {
|
||||
const T = Type.Uppercase(Type.Literal('hello'))
|
||||
Assert.IsTrue(KindGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'HELLO')
|
||||
})
|
||||
it('Should guard for Uppercase 3', () => {
|
||||
const T = Type.Uppercase(Type.Union([Type.Literal('hello'), Type.Literal('world')]))
|
||||
Assert.IsTrue(KindGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'HELLO')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'WORLD')
|
||||
})
|
||||
it('Should guard for Uppercase 4', () => {
|
||||
const T = Type.Uppercase(Type.TemplateLiteral('hello${0|1}'))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$')
|
||||
})
|
||||
it('Should guard for Uppercase 5', () => {
|
||||
const T = Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
|
||||
Assert.IsTrue(KindGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$')
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/kind/void.ts
Normal file
14
test/runtime/type/guard/kind/void.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KindGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/kind/TVoid', () => {
|
||||
it('Should guard for TVoid', () => {
|
||||
const R = KindGuard.IsVoid(Type.Void())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TVoid', () => {
|
||||
const R = KindGuard.IsVoid(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
19
test/runtime/type/guard/type/any.ts
Normal file
19
test/runtime/type/guard/type/any.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TAny', () => {
|
||||
it('Should guard for TAny', () => {
|
||||
const R = TypeGuard.IsAny(Type.Any())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TAny', () => {
|
||||
const R = TypeGuard.IsAny(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TAny with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsAny(Type.Any({ $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
14
test/runtime/type/guard/type/argument.ts
Normal file
14
test/runtime/type/guard/type/argument.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TArgument', () => {
|
||||
it('Should guard for TArgument', () => {
|
||||
const R = TypeGuard.IsArgument(Type.Argument(0))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TArgument', () => {
|
||||
const R = TypeGuard.IsArgument(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
56
test/runtime/type/guard/type/array.ts
Normal file
56
test/runtime/type/guard/type/array.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TArray', () => {
|
||||
it('Should guard for TArray', () => {
|
||||
const R = TypeGuard.IsArray(Type.Array(Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TArray', () => {
|
||||
const R = TypeGuard.IsArray(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should guard for nested object TArray', () => {
|
||||
const R = TypeGuard.IsArray(
|
||||
Type.Array(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for nested object TArray', () => {
|
||||
const R = TypeGuard.IsArray(
|
||||
Type.Array(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: {} as any,
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TArray with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsArray(Type.Array(Type.Number(), { $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TArray with invalid minItems', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsArray(Type.Array(Type.String(), { minItems: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TArray with invalid maxItems', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsArray(Type.Array(Type.String(), { maxItems: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TArray with invalid uniqueItems', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsArray(Type.Array(Type.String(), { uniqueItems: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
22
test/runtime/type/guard/type/async-iterator.ts
Normal file
22
test/runtime/type/guard/type/async-iterator.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TAsyncIterator', () => {
|
||||
it('Should guard for TAsyncIterator', () => {
|
||||
const T = Type.AsyncIterator(Type.Any())
|
||||
const R = TypeGuard.IsAsyncIterator(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TAsyncIterator', () => {
|
||||
const T = null
|
||||
const R = TypeGuard.IsAsyncIterator(T)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TAsyncIterator with invalid $id', () => {
|
||||
//@ts-ignore
|
||||
const T = Type.AsyncIterator(Type.Any(), { $id: 1 })
|
||||
const R = TypeGuard.IsAsyncIterator(T)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
41
test/runtime/type/guard/type/awaited.ts
Normal file
41
test/runtime/type/guard/type/awaited.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/Awaited', () => {
|
||||
it('Should guard for Awaited 1', () => {
|
||||
const T = Type.Awaited(Type.String())
|
||||
const R = TypeGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for Awaited 2', () => {
|
||||
const T = Type.Awaited(Type.Promise(Type.String()))
|
||||
const R = TypeGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for Awaited 3', () => {
|
||||
const T = Type.Awaited(Type.Awaited(Type.Promise(Type.String())))
|
||||
const R = TypeGuard.IsString(T)
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for Awaited 4', () => {
|
||||
const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String()))]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should guard for Awaited 5', () => {
|
||||
const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String())), Type.Number()]))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1]))
|
||||
})
|
||||
it('Should guard for Awaited 6', () => {
|
||||
const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String()))]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should guard for Awaited 7', () => {
|
||||
const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String())), Type.Number()]))
|
||||
Assert.IsTrue(TypeGuard.IsIntersect(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.allOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.allOf[1]))
|
||||
})
|
||||
})
|
||||
19
test/runtime/type/guard/type/bigint.ts
Normal file
19
test/runtime/type/guard/type/bigint.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TBigInt', () => {
|
||||
it('Should guard for TBigInt', () => {
|
||||
const R = TypeGuard.IsBigInt(Type.BigInt())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TBigInt', () => {
|
||||
const R = TypeGuard.IsBigInt(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for BigInt with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsBigInt(Type.BigInt({ $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
19
test/runtime/type/guard/type/boolean.ts
Normal file
19
test/runtime/type/guard/type/boolean.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TBoolean', () => {
|
||||
it('Should guard for TBoolean', () => {
|
||||
const R = TypeGuard.IsBoolean(Type.Boolean())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TBoolean', () => {
|
||||
const R = TypeGuard.IsBoolean(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TBoolean with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsBoolean(Type.Boolean({ $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/type/capitalize.ts
Normal file
33
test/runtime/type/guard/type/capitalize.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { TypeGuard, Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/Capitalize', () => {
|
||||
it('Should guard for Capitalize 1', () => {
|
||||
const T = Type.Capitalize(Type.Literal('hello'), { $id: 'hello', foo: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'Hello')
|
||||
Assert.IsEqual(T.$id, 'hello')
|
||||
Assert.IsEqual(T.foo, 1)
|
||||
})
|
||||
it('Should guard for Capitalize 2', () => {
|
||||
const T = Type.Capitalize(Type.Literal('hello'))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'Hello')
|
||||
})
|
||||
it('Should guard for Capitalize 3', () => {
|
||||
const T = Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')]))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'Hello')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'World')
|
||||
})
|
||||
it('Should guard for Capitalize 4', () => {
|
||||
const T = Type.Capitalize(Type.TemplateLiteral('hello${0|1}'))
|
||||
Assert.IsTrue(TypeGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
|
||||
})
|
||||
it('Should guard for Capitalize 5', () => {
|
||||
const T = Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
|
||||
Assert.IsTrue(TypeGuard.IsTemplateLiteral(T))
|
||||
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
|
||||
})
|
||||
})
|
||||
165
test/runtime/type/guard/type/composite.ts
Normal file
165
test/runtime/type/guard/type/composite.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TComposite', () => {
|
||||
it('Should guard for distinct properties', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })])
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
})
|
||||
it('Should guard for overlapping properties', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() })])
|
||||
Assert.IsTrue(TypeGuard.IsIntersect(T.properties.x))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x.allOf[0]))
|
||||
// @ts-ignore
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x.allOf[1]))
|
||||
})
|
||||
it('Should not produce optional property if all properties are not optional', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() })])
|
||||
Assert.IsFalse(TypeGuard.IsOptional(T.properties.x))
|
||||
})
|
||||
// Note for: https://github.com/sinclairzx81/typebox/issues/419
|
||||
// Determining if a composite property is optional requires a deep check for all properties gathered during a indexed access
|
||||
// call. Currently, there isn't a trivial way to perform this check without running into possibly infinite instantiation issues.
|
||||
// The optional check is only specific to overlapping properties. Singular properties will continue to work as expected. The
|
||||
// rule is "if all composite properties for a key are optional, then the composite property is optional". Defer this test and
|
||||
// document as minor breaking change.
|
||||
//
|
||||
it('Should produce optional property if all composited properties are optional', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.Number()) }),
|
||||
Type.Object({ x: Type.Optional(Type.Number()) })
|
||||
])
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should produce required property if some composited properties are not optional', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.Number()) }),
|
||||
Type.Object({ x: Type.Number() })
|
||||
])
|
||||
Assert.IsFalse(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(T.required!.includes('x'))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should preserve single optional property', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.Number()) }),
|
||||
])
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsEqual(T.required, undefined)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect
|
||||
// ----------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 1', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() }),
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number()
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 2', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ x: Type.Number() }),
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Intersect([Type.Intersect([Type.Number(), Type.Number()]), Type.Number()])
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 3', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Number(),
|
||||
Type.Boolean()
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 4', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Number(),
|
||||
Type.Boolean(),
|
||||
Type.Object({ x: Type.String() })
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.String()
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 5', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.String()) }),
|
||||
Type.Object({ x: Type.String() })
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Intersect([Type.String(), Type.String()])
|
||||
}))
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should composite Intersect 6', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Object({ x: Type.Optional(Type.String()) }),
|
||||
Type.Object({ x: Type.Optional(Type.String()) })
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Optional(Type.Intersect([Type.String(), Type.String()]))
|
||||
}))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Union
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/789
|
||||
// prettier-ignore
|
||||
it('Should composite Union 1 (non-overlapping)', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Union([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() }),
|
||||
]),
|
||||
Type.Union([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
z: Type.Number()
|
||||
}))
|
||||
})
|
||||
// https://github.com/sinclairzx81/typebox/issues/789
|
||||
// prettier-ignore
|
||||
it('Should composite Union 2 (overlapping)', () => {
|
||||
const T = Type.Composite([
|
||||
Type.Union([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ x: Type.Number() }),
|
||||
]),
|
||||
Type.Union([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
])
|
||||
])
|
||||
Assert.IsEqual(T, Type.Object({
|
||||
x: Type.Intersect([Type.Union([Type.Number(), Type.Number()]), Type.Number()])
|
||||
}))
|
||||
})
|
||||
})
|
||||
33
test/runtime/type/guard/type/computed.ts
Normal file
33
test/runtime/type/guard/type/computed.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TComputed', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Schema
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Schema', () => {
|
||||
const T = Type.Partial(Type.Ref('A'))
|
||||
Assert.IsTrue(TypeGuard.IsComputed(T))
|
||||
Assert.IsTrue(TypeGuard.IsSchema(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Record 1', () => {
|
||||
const T = Type.Record(Type.String(), Type.String())
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
})
|
||||
it('Should guard for Record 3', () => {
|
||||
const T = Type.Record(Type.String(), Type.Ref('A'))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
})
|
||||
it('Should guard for Record 3', () => {
|
||||
const T = Type.Record(Type.String(), Type.Partial(Type.Ref('A')))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
})
|
||||
it('Should guard for Record 4', () => {
|
||||
const T = Type.Record(Type.Ref('A'), Type.String())
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
})
|
||||
124
test/runtime/type/guard/type/const.ts
Normal file
124
test/runtime/type/guard/type/const.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { TypeGuard, ValueGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TConstT', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Identity Types
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TConst 1', () => {
|
||||
const T = Type.Const(undefined)
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsUndefined(T))
|
||||
})
|
||||
it('Should guard for TConst 2', () => {
|
||||
const T = Type.Const(null)
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsNull(T))
|
||||
})
|
||||
it('Should guard for TConst 3', () => {
|
||||
const T = Type.Const(Symbol())
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsSymbol(T))
|
||||
})
|
||||
it('Should guard for TConst 4', () => {
|
||||
const T = Type.Const(1 as const)
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 1)
|
||||
})
|
||||
it('Should guard for TConst 5', () => {
|
||||
const T = Type.Const('hello' as const)
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should guard for TConst 6', () => {
|
||||
const T = Type.Const(true as const)
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, true)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Complex Types
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TConst 7', () => {
|
||||
const T = Type.Const(100n as const)
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
// TS disparity because TLiteral does not support Bigint
|
||||
Assert.IsTrue(TypeGuard.IsBigInt(T))
|
||||
})
|
||||
it('Should guard for TConst 8', () => {
|
||||
const T = Type.Const(new Date())
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsDate(T))
|
||||
})
|
||||
it('Should guard for TConst 9', () => {
|
||||
const T = Type.Const(new Uint8Array())
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsUint8Array(T))
|
||||
})
|
||||
it('Should guard for TConst 10', () => {
|
||||
const T = Type.Const(function () {})
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsFunction(T))
|
||||
Assert.IsTrue(T.parameters.length === 0)
|
||||
Assert.IsTrue(TypeGuard.IsUnknown(T.returns))
|
||||
})
|
||||
it('Should guard for TConst 11', () => {
|
||||
const T = Type.Const(new (class {})())
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
// Object types that are neither Date or Uint8Array evaluate as empty objects
|
||||
Assert.IsEqual(T.properties, {})
|
||||
})
|
||||
it('Should guard for TConst 12', () => {
|
||||
const T = Type.Const((function* (): any {})())
|
||||
const R = ValueGuard.IsIterator((function* (): any {})())
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
it('Should guard for TConst 13', () => {
|
||||
const T = Type.Const((async function* (): any {})())
|
||||
const R = ValueGuard.IsAsyncIterator((function* (): any {})())
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
it('Should guard for TConst 14', () => {
|
||||
const T = Type.Const({
|
||||
x: 1,
|
||||
y: {
|
||||
z: 2,
|
||||
},
|
||||
} as const)
|
||||
// root
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
// x
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T.properties.x))
|
||||
Assert.IsEqual(T.properties.x.const, 1)
|
||||
// y
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T.properties.y))
|
||||
// y.z
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y.properties.z))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T.properties.y.properties.z))
|
||||
Assert.IsEqual(T.properties.y.properties.z.const, 2)
|
||||
})
|
||||
it('Should guard for TConst 15', () => {
|
||||
const T = Type.Const([1, 2, 3] as const)
|
||||
// root (arrays are always readonly as root)
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T))
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(T.items?.length === 3)
|
||||
// 0
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T.items![0]))
|
||||
// 1
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.items![1]))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T.items![1]))
|
||||
// 2
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.items![2]))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T.items![2]))
|
||||
})
|
||||
})
|
||||
35
test/runtime/type/guard/type/constructor.ts
Normal file
35
test/runtime/type/guard/type/constructor.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TConstructor', () => {
|
||||
it('Should guard for TConstructor', () => {
|
||||
const R = TypeGuard.IsConstructor(Type.Constructor([], Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TConstructor', () => {
|
||||
const R = TypeGuard.IsConstructor(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TConstructor with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsConstructor(Type.Constructor([], Type.Number(), { $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TConstructor with invalid Params', () => {
|
||||
const R = TypeGuard.IsConstructor(Type.Constructor([{} as any, {} as any], Type.Number()))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TConstructor with invalid Return', () => {
|
||||
const R = TypeGuard.IsConstructor(Type.Constructor([], {} as any))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should guard for TConstructor with empty Rest Tuple', () => {
|
||||
const R = TypeGuard.IsConstructor(Type.Constructor(Type.Rest(Type.Tuple([])), Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should guard for TConstructor with Rest Tuple', () => {
|
||||
const R = TypeGuard.IsConstructor(Type.Constructor(Type.Rest(Type.Tuple([Type.Number(), Type.String()])), Type.Number()))
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
})
|
||||
44
test/runtime/type/guard/type/date.ts
Normal file
44
test/runtime/type/guard/type/date.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TDate', () => {
|
||||
it('Should guard for TDate', () => {
|
||||
const R = TypeGuard.IsDate(Type.Date())
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not guard for TDate', () => {
|
||||
const R = TypeGuard.IsDate(null)
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TDate with invalid $id', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsDate(Type.Date({ $id: 1 }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TDate with invalid exclusiveMaximumTimestamp', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsDate(Type.Date({ exclusiveMaximumTimestamp: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TDate with invalid exclusiveMinimumTimestamp', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsDate(Type.Date({ exclusiveMinimumTimestamp: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TDate with invalid maximumTimestamp', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsDate(Type.Date({ maximumTimestamp: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TDate with invalid minimumTimestamp', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsDate(Type.Date({ minimumTimestamp: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should not guard for TDate with invalid multipleOfTimestamp', () => {
|
||||
// @ts-ignore
|
||||
const R = TypeGuard.IsDate(Type.Date({ multipleOfTimestamp: '1' }))
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
})
|
||||
143
test/runtime/type/guard/type/enum.ts
Normal file
143
test/runtime/type/guard/type/enum.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
describe('guard/type/TEnum', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Options
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Options 1', () => {
|
||||
const T = Type.Enum({ x: 1 }, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
it('Should guard for Options 2', () => {
|
||||
enum E {
|
||||
x,
|
||||
}
|
||||
const T = Type.Enum(E, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
it('Should guard for Options 3', () => {
|
||||
enum E {}
|
||||
const T = Type.Enum(E, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
it('Should guard for Options 4', () => {
|
||||
const T = Type.Enum({}, { extra: 'hello', $id: 'T' })
|
||||
Assert.IsEqual(T.extra, 'hello')
|
||||
Assert.IsEqual(T.$id, 'T')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Empty
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for Empty 1', () => {
|
||||
const T = Type.Enum({})
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard for Empty 2', () => {
|
||||
enum E {}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Enum
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TEnum Enum 0', () => {
|
||||
enum E {}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard for TEnum Enum 1', () => {
|
||||
enum E {
|
||||
A,
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, E.A)
|
||||
})
|
||||
it('Should guard for TEnum Enum 2', () => {
|
||||
enum E {
|
||||
A = 1,
|
||||
B = 2,
|
||||
C = 3,
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, E.A)
|
||||
Assert.IsEqual(T.anyOf[1].const, E.B)
|
||||
Assert.IsEqual(T.anyOf[2].const, E.C)
|
||||
})
|
||||
it('Should guard for TEnum Enum 3', () => {
|
||||
enum E {
|
||||
A = 'X',
|
||||
B = 'Y',
|
||||
C = 'Z',
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, E.A)
|
||||
Assert.IsEqual(T.anyOf[1].const, E.B)
|
||||
Assert.IsEqual(T.anyOf[2].const, E.C)
|
||||
})
|
||||
it('Should guard for TEnum Enum 4', () => {
|
||||
enum E {
|
||||
A = 'X',
|
||||
B = 'Y',
|
||||
C = 'X',
|
||||
}
|
||||
const T = Type.Enum(E)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, E.A)
|
||||
Assert.IsEqual(T.anyOf[1].const, E.B)
|
||||
Assert.IsEqual(T.anyOf.length, 2)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Object Literal
|
||||
// ----------------------------------------------------------------
|
||||
it('Should guard for TEnum Object Literal 0', () => {
|
||||
const T = Type.Enum({})
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 1', () => {
|
||||
const T = Type.Enum({ A: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 1)
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 2', () => {
|
||||
const T = Type.Enum({
|
||||
A: 1,
|
||||
B: 2,
|
||||
C: 3,
|
||||
})
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 1)
|
||||
Assert.IsEqual(T.anyOf[1].const, 2)
|
||||
Assert.IsEqual(T.anyOf[2].const, 3)
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 3', () => {
|
||||
const T = Type.Enum({
|
||||
A: 'X',
|
||||
B: 'Y',
|
||||
C: 'Z',
|
||||
})
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'X')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'Y')
|
||||
Assert.IsEqual(T.anyOf[2].const, 'Z')
|
||||
})
|
||||
it('Should guard for TEnum Object Literal 4', () => {
|
||||
const T = Type.Enum({
|
||||
A: 'X',
|
||||
B: 'Y',
|
||||
C: 'X',
|
||||
})
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'X')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'Y')
|
||||
Assert.IsEqual(T.anyOf.length, 2)
|
||||
})
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user