From 3719b3eaff59fafe077bc47cf8ada4940f9499f2 Mon Sep 17 00:00:00 2001 From: sinclairzx81 Date: Sun, 21 Apr 2024 01:28:28 +0900 Subject: [PATCH] Revision 0.32.22 (#840) * Support Optional and Readonly Function Arguments * Version --- package-lock.json | 4 ++-- package.json | 2 +- src/type/constructor/constructor.ts | 25 +++++++++++++++++-------- src/type/function/function.ts | 26 ++++++++++++++++++-------- test/static/constructor.ts | 20 ++++++++++++++++++++ test/static/function.ts | 22 ++++++++++++++++++++++ 6 files changed, 80 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2dde718..5249c5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@sinclair/typebox", - "version": "0.32.21", + "version": "0.32.22", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@sinclair/typebox", - "version": "0.32.21", + "version": "0.32.22", "license": "MIT", "devDependencies": { "@arethetypeswrong/cli": "^0.13.2", diff --git a/package.json b/package.json index ad32abe..0340aa4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sinclair/typebox", - "version": "0.32.21", + "version": "0.32.22", "description": "Json Schema Type Builder with Static Type Resolution for TypeScript", "keywords": [ "typescript", diff --git a/src/type/constructor/constructor.ts b/src/type/constructor/constructor.ts index 948d0aa..9983862 100644 --- a/src/type/constructor/constructor.ts +++ b/src/type/constructor/constructor.ts @@ -29,28 +29,37 @@ THE SOFTWARE. import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import type { Ensure } from '../helpers/index' +import type { TReadonlyOptional } from '../readonly-optional/index' +import type { TReadonly } from '../readonly/index' +import type { TOptional } from '../optional/index' import { CloneType, CloneRest } from '../clone/type' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ -// TConstructorStatic +// StaticConstructor // ------------------------------------------------------------------ -type ConstructorStaticReturnType = Static +type StaticReturnType = Static // prettier-ignore -type ConstructorStaticParameters = +type StaticParameter = + T extends TReadonlyOptional ? [Readonly>?] : + T extends TReadonly ? [Readonly>] : + T extends TOptional ? [Static?] : + [Static] +// prettier-ignore +type StaticParameters = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? ConstructorStaticParameters]> + ? StaticParameters]> : Acc -// prettier-ignore -type ConstructorStatic = ( - Ensure) => ConstructorStaticReturnType> ) +// prettier-ignore +type StaticConstructor = + Ensure) => StaticReturnType> // ------------------------------------------------------------------ // TConstructor // ------------------------------------------------------------------ export interface TConstructor extends TSchema { [Kind]: 'Constructor' - static: ConstructorStatic + static: StaticConstructor type: 'Constructor' parameters: T returns: U diff --git a/src/type/function/function.ts b/src/type/function/function.ts index 6f594df..340e5ba 100644 --- a/src/type/function/function.ts +++ b/src/type/function/function.ts @@ -29,28 +29,38 @@ THE SOFTWARE. import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import type { Ensure } from '../helpers/index' +import type { TReadonlyOptional } from '../readonly-optional/index' +import type { TReadonly } from '../readonly/index' +import type { TOptional } from '../optional/index' import { CloneType, CloneRest } from '../clone/type' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ -// FunctionStatic +// StaticFunction // ------------------------------------------------------------------ -type FunctionStaticReturnType = Static +type StaticReturnType = Static // prettier-ignore -type FunctionStaticParameters = +type StaticParameter = + T extends TReadonlyOptional ? [Readonly>?] : + T extends TReadonly ? [Readonly>] : + T extends TOptional ? [Static?] : + [Static] +// prettier-ignore +type StaticParameters = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? FunctionStaticParameters]> + ? StaticParameters]> : Acc -// prettier-ignore -type FunctionStatic = ( - Ensure<(...param: FunctionStaticParameters) => FunctionStaticReturnType> ) +// prettier-ignore +type StaticFunction = + Ensure<(...params: StaticParameters) => StaticReturnType> + // ------------------------------------------------------------------ // TFunction // ------------------------------------------------------------------ export interface TFunction extends TSchema { [Kind]: 'Function' - static: FunctionStatic + static: StaticFunction type: 'Function' parameters: T returns: U diff --git a/test/static/constructor.ts b/test/static/constructor.ts index c91d398..59e435c 100644 --- a/test/static/constructor.ts +++ b/test/static/constructor.ts @@ -13,6 +13,26 @@ import { Type } from '@sinclair/typebox' })) Expect(T).ToStatic { method: new (param_0: number, param_1: string) => boolean }>() } +{ + // readonly-optional + const T = Type.Constructor([Type.ReadonlyOptional(Type.Array(Type.Number()))], Type.Number()) + Expect(T).ToStaticDecode number>() +} +{ + // readonly + const T = Type.Constructor([Type.Readonly(Type.Array(Type.Number()))], Type.Number()) + Expect(T).ToStaticDecode number>() +} +{ + // optional 1 + const T = Type.Constructor([Type.Optional(Type.Number())], Type.Number()) + Expect(T).ToStaticDecode number>() +} +{ + // optional 2 + const T = Type.Constructor([Type.Number(), Type.Optional(Type.Number())], Type.Number()) + Expect(T).ToStaticDecode number>() +} { // decode 2 const S = Type.Transform(Type.Integer()) diff --git a/test/static/function.ts b/test/static/function.ts index a204187..1ae3404 100644 --- a/test/static/function.ts +++ b/test/static/function.ts @@ -14,6 +14,28 @@ import { Type } from '@sinclair/typebox' })) Expect(T).ToStatic<(param_0: number, param_1: string) => { method: (param_0: number, param_1: string) => boolean }>() } +{ + // readonly-optional + const T = Type.Function([Type.ReadonlyOptional(Type.Array(Type.Number()))], Type.Number()) + Expect(T).ToStaticDecode<(param_0?: readonly number[]) => number>() +} +{ + // readonly + const T = Type.Function([Type.Readonly(Type.Array(Type.Number()))], Type.Number()) + Expect(T).ToStaticDecode<(param_0: readonly number[]) => number>() +} +{ + // optional 1 + const T = Type.Function([Type.Optional(Type.Number())], Type.Number()) + Expect(T).ToStaticDecode<(param_0?: number) => number>() +} +{ + // optional 2 + const T = Type.Function([Type.Number(), Type.Optional(Type.Number())], Type.Number()) + Expect(T).ToStaticDecode<(param_0: number, param_1?: number) => number>() +} +const F = Type.Constructor([Type.Readonly(Type.Array(Type.String()))], Type.Number()) + { // decode 2 const S = Type.Transform(Type.Integer())