From e1b923cdbafe5d408bb738fec0ce7f9749c9f034 Mon Sep 17 00:00:00 2001 From: sinclairzx81 Date: Tue, 11 Apr 2023 14:41:51 +0900 Subject: [PATCH] Record Option Overloads (#377) --- package-lock.json | 4 +-- package.json | 2 +- src/typebox.ts | 10 +++--- test/runtime/type/guard/record.ts | 57 ++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3729af7..74cb8e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index d118383..3d670d2 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/typebox.ts b/src/typebox.ts index a25d5b0..997128a 100644 --- a/src/typebox.ts +++ b/src/typebox.ts @@ -2365,15 +2365,15 @@ export class StandardTypeBuilder extends TypeBuilder { }, options) } /** `[Standard]` Creates a Record type */ - public Record[]>, T extends TSchema>(key: K, schema: T): RecordUnionLiteralType + public Record[]>, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordUnionLiteralType /** `[Standard]` Creates a Record type */ - public Record, T extends TSchema>(key: K, schema: T): RecordLiteralType + public Record, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): RecordLiteralType /** `[Standard]` Creates a Record type */ - public Record(key: K, schema: T): RecordTemplateLiteralType + public Record(key: K, schema: T, options?: ObjectOptions): RecordTemplateLiteralType /** `[Standard]` Creates a Record type */ - public Record(key: K, schema: T): RecordNumberType + public Record(key: K, schema: T, options?: ObjectOptions): RecordNumberType /** `[Standard]` Creates a Record type */ - public Record(key: K, schema: T): RecordStringType + public Record(key: K, schema: T, options?: ObjectOptions): RecordStringType /** `[Standard]` Creates a Record type */ public Record(key: RecordKey, schema: TSchema, options: ObjectOptions = {}) { if (TypeGuard.TTemplateLiteral(key)) { diff --git a/test/runtime/type/guard/record.ts b/test/runtime/type/guard/record.ts index 2418c0e..45ebcb4 100644 --- a/test/runtime/type/guard/record.ts +++ b/test/runtime/type/guard/record.ts @@ -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)