mirror of
https://github.com/zoriya/typebox.git
synced 2026-05-31 02:07:17 +00:00
Revision 0.32.35 (#932)
* Support Any and Never Record Keys * Update Require Property Message * Ensure Record Enumerable on Convert * TypeScript 5.5.3 * Version
This commit is contained in:
@@ -238,4 +238,56 @@ describe('compiler-ajv/Record', () => {
|
||||
key2: 1,
|
||||
})
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate for string keys', () => {
|
||||
const T = Type.Record(Type.String(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Ok(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
it('Should validate for number keys', () => {
|
||||
const T = Type.Record(Type.Number(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Fail(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Ok(T, {
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
it('Should validate for any keys', () => {
|
||||
const T = Type.Record(Type.Any(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Ok(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
it('Should validate for never keys', () => {
|
||||
const T = Type.Record(Type.Never(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Ok(T, {})
|
||||
Fail(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -269,4 +269,56 @@ describe('compiler/Record', () => {
|
||||
key2: 1,
|
||||
})
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate for string keys', () => {
|
||||
const T = Type.Record(Type.String(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Ok(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
it('Should validate for number keys', () => {
|
||||
const T = Type.Record(Type.Number(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Fail(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Ok(T, {
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
it('Should validate for any keys', () => {
|
||||
const T = Type.Record(Type.Any(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Ok(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
it('Should validate for never keys', () => {
|
||||
const T = Type.Record(Type.Never(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
Ok(T, {})
|
||||
Fail(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TypeGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNumber } from '@sinclair/typebox'
|
||||
import { TypeGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNeverExact } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
@@ -21,8 +21,11 @@ describe('guard/kind/TRecord', () => {
|
||||
})
|
||||
it('Should guard overload 3', () => {
|
||||
// @ts-ignore
|
||||
const T = Type.Record(Type.Union([]), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
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
|
||||
@@ -89,6 +92,23 @@ describe('guard/kind/TRecord', () => {
|
||||
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
|
||||
// -------------------------------------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TypeGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNumber } from '@sinclair/typebox'
|
||||
import { TypeGuard, PatternNumberExact, PatternStringExact, PatternNeverExact, PatternString, PatternNumber } from '@sinclair/typebox'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../../assert/index'
|
||||
|
||||
@@ -21,8 +21,11 @@ describe('guard/type/TRecord', () => {
|
||||
})
|
||||
it('Should guard overload 3', () => {
|
||||
// @ts-ignore
|
||||
const T = Type.Record(Type.Union([]), Type.String(), { extra: 1 })
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
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
|
||||
@@ -89,6 +92,25 @@ describe('guard/type/TRecord', () => {
|
||||
Assert.IsTrue(TypeGuard.IsNull(R.properties.Y))
|
||||
Assert.IsTrue(TypeGuard.IsNull(R.properties.Z))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
//
|
||||
// Added overload for Any and Never Keys
|
||||
// ----------------------------------------------------------------
|
||||
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
|
||||
// -------------------------------------------------------------
|
||||
|
||||
@@ -236,4 +236,62 @@ describe('value/check/Record', () => {
|
||||
const R = Value.Check(T, { 1: '', 2: '', x: true })
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate for string keys', () => {
|
||||
const T = Type.Record(Type.String(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
it('Should validate for number keys', () => {
|
||||
const T = Type.Record(Type.Number(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R1 = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
const R2 = Value.Check(T, {
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R1, false)
|
||||
Assert.IsEqual(R2, true)
|
||||
})
|
||||
it('Should validate for any keys', () => {
|
||||
const T = Type.Record(Type.Any(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
it('Should validate for never keys', () => {
|
||||
const T = Type.Record(Type.Never(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R1 = Value.Check(T, {})
|
||||
const R2 = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R1, true)
|
||||
Assert.IsEqual(R2, false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -8,4 +8,37 @@ describe('value/convert/Record', () => {
|
||||
const V = Value.Convert(T, { x: '42', y: '24', z: 'hello' })
|
||||
Assert.IsEqual(V, { x: 42, y: 24, z: 'hello' })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/930
|
||||
// ----------------------------------------------------------------
|
||||
it('Should convert record union 1', () => {
|
||||
const T = Type.Union([Type.Null(), Type.Record(Type.Number(), Type.Any())])
|
||||
const V = Value.Convert(T, {})
|
||||
Assert.IsEqual(V, {})
|
||||
})
|
||||
it('Should convert record union 2', () => {
|
||||
const T = Type.Union([Type.Record(Type.Number(), Type.Any()), Type.Null()])
|
||||
const V = Value.Convert(T, {})
|
||||
Assert.IsEqual(V, {})
|
||||
})
|
||||
it('Should convert record union 3', () => {
|
||||
const T = Type.Union([Type.Null(), Type.Record(Type.Number(), Type.Any())])
|
||||
const V = Value.Convert(T, null)
|
||||
Assert.IsEqual(V, null)
|
||||
})
|
||||
it('Should convert record union 4', () => {
|
||||
const T = Type.Union([Type.Record(Type.Number(), Type.Any()), Type.Null()])
|
||||
const V = Value.Convert(T, null)
|
||||
Assert.IsEqual(V, null)
|
||||
})
|
||||
it('Should convert record union 5', () => {
|
||||
const T = Type.Union([Type.Null(), Type.Record(Type.Number(), Type.Any())])
|
||||
const V = Value.Convert(T, 'NULL')
|
||||
Assert.IsEqual(V, null)
|
||||
})
|
||||
it('Should convert record union 6', () => {
|
||||
const T = Type.Union([Type.Record(Type.Number(), Type.Any()), Type.Null()])
|
||||
const V = Value.Convert(T, 'NULL')
|
||||
Assert.IsEqual(V, null)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -189,3 +189,16 @@ import { Type, Static } from '@sinclair/typebox'
|
||||
'$propC': string
|
||||
}>()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
// ------------------------------------------------------------------
|
||||
{
|
||||
const K = Type.Any()
|
||||
const T = Type.Record(K, Type.String())
|
||||
Expect(T).ToStatic<Record<string, string>>()
|
||||
}
|
||||
{
|
||||
const K = Type.Never()
|
||||
const T = Type.Record(K, Type.String())
|
||||
Expect(T).ToStatic<{}>()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user