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:
sinclairzx81
2024-07-23 03:08:57 +09:00
committed by GitHub
parent 83e05bb43c
commit e686997fcd
14 changed files with 302 additions and 21 deletions
+52
View File
@@ -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,
})
})
})
+52
View File
@@ -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,
})
})
})
+23 -3
View File
@@ -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
// -------------------------------------------------------------
+25 -3
View File
@@ -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
// -------------------------------------------------------------
+58
View File
@@ -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)
})
})
+33
View File
@@ -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)
})
})
+13
View File
@@ -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<{}>()
}