Record Option Overloads (#377)

This commit is contained in:
sinclairzx81
2023-04-11 14:41:51 +09:00
committed by GitHub
parent 39fccd596e
commit e1b923cdba
4 changed files with 64 additions and 9 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@sinclair/typebox",
"version": "0.27.2",
"version": "0.27.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@sinclair/typebox",
"version": "0.27.2",
"version": "0.27.3",
"license": "MIT",
"devDependencies": {
"@sinclair/hammer": "^0.17.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.27.2",
"version": "0.27.3",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
+5 -5
View File
@@ -2365,15 +2365,15 @@ export class StandardTypeBuilder extends TypeBuilder {
}, options)
}
/** `[Standard]` Creates a Record type */
public Record<K extends TUnion<TLiteral<string | number>[]>, T extends TSchema>(key: K, schema: T): RecordUnionLiteralType<K, T>
public Record<K extends TUnion<TLiteral<string | number>[]>, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordUnionLiteralType<K, T>
/** `[Standard]` Creates a Record type */
public Record<K extends TLiteral<string | number>, T extends TSchema>(key: K, schema: T): RecordLiteralType<K, T>
public Record<K extends TLiteral<string | number>, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordLiteralType<K, T>
/** `[Standard]` Creates a Record type */
public Record<K extends TTemplateLiteral, T extends TSchema>(key: K, schema: T): RecordTemplateLiteralType<K, T>
public Record<K extends TTemplateLiteral, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordTemplateLiteralType<K, T>
/** `[Standard]` Creates a Record type */
public Record<K extends TInteger | TNumber, T extends TSchema>(key: K, schema: T): RecordNumberType<K, T>
public Record<K extends TInteger | TNumber, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordNumberType<K, T>
/** `[Standard]` Creates a Record type */
public Record<K extends TString, T extends TSchema>(key: K, schema: T): RecordStringType<K, T>
public Record<K extends TString, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordStringType<K, T>
/** `[Standard]` Creates a Record type */
public Record(key: RecordKey, schema: TSchema, options: ObjectOptions = {}) {
if (TypeGuard.TTemplateLiteral(key)) {
+56 -1
View File
@@ -1,8 +1,63 @@
import { TypeGuard } from '@sinclair/typebox'
import { TypeGuard, PatternNumberExact, PatternStringExact, PatternNumber } from '@sinclair/typebox'
import { Type } from '@sinclair/typebox'
import { Assert } from '../../assert/index'
describe('type/guard/TRecord', () => {
// -------------------------------------------------------------
// Overloads
// -------------------------------------------------------------
it('Should guard overload 1', () => {
const T = Type.Record(Type.Union([Type.Literal('A'), Type.Literal('B')]), Type.String(), { extra: 1 })
Assert.equal(TypeGuard.TObject(T), true)
Assert.equal(TypeGuard.TString(T.properties.A), true)
Assert.equal(TypeGuard.TString(T.properties.B), true)
Assert.equal(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.equal(TypeGuard.TObject(T), true)
Assert.equal(TypeGuard.TString(T.properties.A), true)
Assert.equal(T.extra, 1)
})
it('Should guard overload 3', () => {
// @ts-ignore
Assert.throws(() => Type.Record(Type.Union([]), Type.String(), { extra: 1 }))
})
it('Should guard overload 4', () => {
const T = Type.Record(Type.Literal('A'), Type.String(), { extra: 1 })
Assert.equal(TypeGuard.TObject(T), true)
Assert.equal(TypeGuard.TString(T.properties.A), true)
Assert.equal(T.extra, 1)
})
it('Should guard overload 5', () => {
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.equal(TypeGuard.TObject(T), true)
Assert.equal(TypeGuard.TString(T.properties.helloA), true)
Assert.equal(TypeGuard.TString(T.properties.helloB), true)
Assert.equal(T.extra, 1)
})
it('Should guard overload 6', () => {
const T = Type.Record(Type.Number(), Type.String(), { extra: 1 })
Assert.equal(TypeGuard.TRecord(T), true)
Assert.equal(TypeGuard.TString(T.patternProperties[PatternNumberExact]), true)
Assert.equal(T.extra, 1)
})
it('Should guard overload 7', () => {
const T = Type.Record(Type.Integer(), Type.String(), { extra: 1 })
Assert.equal(TypeGuard.TRecord(T), true)
Assert.equal(TypeGuard.TString(T.patternProperties[PatternNumberExact]), true)
Assert.equal(T.extra, 1)
})
it('Should guard overload 8', () => {
const T = Type.Record(Type.String(), Type.String(), { extra: 1 })
Assert.equal(TypeGuard.TRecord(T), true)
Assert.equal(TypeGuard.TString(T.patternProperties[PatternStringExact]), true)
Assert.equal(T.extra, 1)
})
// -------------------------------------------------------------
// Variants
// -------------------------------------------------------------
it('Should guard for TRecord', () => {
const R = TypeGuard.TRecord(Type.Record(Type.String(), Type.Number()))
Assert.equal(R, true)