Skip to content

Commit

Permalink
Add Literal Passthrough on Required and Partial
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Feb 14, 2025
1 parent 196a776 commit fca9f0d
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 7 deletions.
9 changes: 6 additions & 3 deletions src/type/partial/partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ import { type TRef, Ref } from '../ref/index'
import { type TBigInt } from '../bigint/index'
import { type TBoolean } from '../boolean/index'
import { type TInteger } from '../integer/index'
import { type TLiteral } from '../literal/index'
import { type TNull } from '../null/index'
import { type TNumber } from '../number/index'
import { type TString } from '../string/index'
import { type TSymbol } from '../symbol/index'
import { type TNull } from '../null/index'
import { type TUndefined } from '../undefined/index'

import { Discard } from '../discard/index'
Expand Down Expand Up @@ -138,8 +139,9 @@ function PartialResolve<Type extends TSchema>(type: Type): TPartial<Type> {
KindGuard.IsBigInt(type) ? type :
KindGuard.IsBoolean(type) ? type :
KindGuard.IsInteger(type) ? type :
KindGuard.IsNumber(type) ? type :
KindGuard.IsLiteral(type) ? type :
KindGuard.IsNull(type) ? type :
KindGuard.IsNumber(type) ? type :
KindGuard.IsString(type) ? type :
KindGuard.IsSymbol(type) ? type :
KindGuard.IsUndefined(type) ? type :
Expand All @@ -163,8 +165,9 @@ export type TPartial<Type extends TSchema> = (
Type extends TBigInt ? Type :
Type extends TBoolean ? Type :
Type extends TInteger ? Type :
Type extends TNumber ? Type :
Type extends TLiteral ? Type :
Type extends TNull ? Type :
Type extends TNumber ? Type :
Type extends TString ? Type :
Type extends TSymbol ? Type :
Type extends TUndefined ? Type :
Expand Down
10 changes: 7 additions & 3 deletions src/type/required/required.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ import { type TRef, Ref } from '../ref/index'
import { type TBigInt } from '../bigint/index'
import { type TBoolean } from '../boolean/index'
import { type TInteger } from '../integer/index'
import { type TLiteral } from '../literal/index'
import { type TNull } from '../null/index'
import { type TNumber } from '../number/index'
import { type TString } from '../string/index'
import { type TSymbol } from '../symbol/index'
import { type TNull } from '../null/index'
import { type TUndefined } from '../undefined/index'

import { OptionalKind, TransformKind } from '../symbols/index'
import { Discard } from '../discard/index'
import { RequiredFromMappedResult, type TRequiredFromMappedResult } from './required-from-mapped-result'
Expand Down Expand Up @@ -137,8 +139,9 @@ function RequiredResolve<Type extends TSchema>(type: Type): TRequired<Type> {
KindGuard.IsBigInt(type) ? type :
KindGuard.IsBoolean(type) ? type :
KindGuard.IsInteger(type) ? type :
KindGuard.IsNumber(type) ? type :
KindGuard.IsLiteral(type) ? type :
KindGuard.IsNull(type) ? type :
KindGuard.IsNumber(type) ? type :
KindGuard.IsString(type) ? type :
KindGuard.IsSymbol(type) ? type :
KindGuard.IsUndefined(type) ? type :
Expand All @@ -162,8 +165,9 @@ export type TRequired<Type extends TSchema> = (
Type extends TBigInt ? Type :
Type extends TBoolean ? Type :
Type extends TInteger ? Type :
Type extends TNumber ? Type :
Type extends TLiteral ? Type :
Type extends TNull ? Type :
Type extends TNumber ? Type :
Type extends TString ? Type :
Type extends TSymbol ? Type :
Type extends TUndefined ? Type :
Expand Down
32 changes: 32 additions & 0 deletions test/runtime/type/guard/kind/partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,36 @@ describe('guard/kind/TPartial', () => {
const R = Type.Partial(S)
Assert.IsFalse(TransformKind in R)
})
// ------------------------------------------------------------------
// Intrinsic Passthough
// https://github.com/sinclairzx81/typebox/issues/1169
// ------------------------------------------------------------------
it('Should pass through on intrinsic types on union 1', () => {
const T = Type.Partial(
Type.Union([
Type.Number(),
Type.Object({
x: Type.Number(),
}),
]),
)
Assert.IsTrue(KindGuard.IsUnion(T))
Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0]))
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
Assert.IsTrue(KindGuard.IsOptional(T.anyOf[1].properties.x))
})
it('Should pass through on intrinsic types on union 2', () => {
const T = Type.Partial(
Type.Union([
Type.Literal(1),
Type.Object({
x: Type.Number(),
}),
]),
)
Assert.IsTrue(KindGuard.IsUnion(T))
Assert.IsTrue(KindGuard.IsLiteral(T.anyOf[0]))
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
Assert.IsTrue(KindGuard.IsOptional(T.anyOf[1].properties.x))
})
})
32 changes: 32 additions & 0 deletions test/runtime/type/guard/kind/required.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,36 @@ describe('guard/kind/TRequired', () => {
const R = Type.Required(S)
Assert.IsFalse(TransformKind in R)
})
// ------------------------------------------------------------------
// Intrinsic Passthough
// https://github.com/sinclairzx81/typebox/issues/1169
// ------------------------------------------------------------------
it('Should pass through on intrinsic types on union', () => {
const T = Type.Required(
Type.Union([
Type.Number(),
Type.Object({
x: Type.Optional(Type.Number()),
}),
]),
)
Assert.IsTrue(KindGuard.IsUnion(T))
Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0]))
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
Assert.IsFalse(KindGuard.IsOptional(T.anyOf[1].properties.x))
})
it('Should pass through on intrinsic types on union', () => {
const T = Type.Required(
Type.Union([
Type.Literal(1),
Type.Object({
x: Type.Optional(Type.Number()),
}),
]),
)
Assert.IsTrue(KindGuard.IsUnion(T))
Assert.IsTrue(KindGuard.IsLiteral(T.anyOf[0]))
Assert.IsTrue(KindGuard.IsObject(T.anyOf[1]))
Assert.IsFalse(KindGuard.IsOptional(T.anyOf[1].properties.x))
})
})
16 changes: 15 additions & 1 deletion test/runtime/type/guard/type/partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe('guard/type/TPartial', () => {
// Intrinsic Passthough
// https://github.com/sinclairzx81/typebox/issues/1169
// ------------------------------------------------------------------
it('Should pass through on intrinsic types on union', () => {
it('Should pass through on intrinsic types on union 1', () => {
const T = Type.Partial(
Type.Union([
Type.Number(),
Expand All @@ -91,4 +91,18 @@ describe('guard/type/TPartial', () => {
Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1]))
Assert.IsTrue(TypeGuard.IsOptional(T.anyOf[1].properties.x))
})
it('Should pass through on intrinsic types on union 2', () => {
const T = Type.Partial(
Type.Union([
Type.Literal(1),
Type.Object({
x: Type.Number(),
}),
]),
)
Assert.IsTrue(TypeGuard.IsUnion(T))
Assert.IsTrue(TypeGuard.IsLiteral(T.anyOf[0]))
Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1]))
Assert.IsTrue(TypeGuard.IsOptional(T.anyOf[1].properties.x))
})
})
14 changes: 14 additions & 0 deletions test/runtime/type/guard/type/required.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,18 @@ describe('guard/type/TRequired', () => {
Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1]))
Assert.IsFalse(TypeGuard.IsOptional(T.anyOf[1].properties.x))
})
it('Should pass through on intrinsic types on union', () => {
const T = Type.Required(
Type.Union([
Type.Literal(1),
Type.Object({
x: Type.Optional(Type.Number()),
}),
]),
)
Assert.IsTrue(TypeGuard.IsUnion(T))
Assert.IsTrue(TypeGuard.IsLiteral(T.anyOf[0]))
Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1]))
Assert.IsFalse(TypeGuard.IsOptional(T.anyOf[1].properties.x))
})
})
7 changes: 7 additions & 0 deletions test/static/partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,10 @@ import * as Types from '@sinclair/typebox'
})]))
Expect(T).ToStatic<number | { x?: number }>
}
// prettier-ignore
{
const T = Type.Partial(Type.Union([Type.Literal(1), Type.Object({
x: Type.Number()
})]))
Expect(T).ToStatic<1 | { x?: number }>
}
7 changes: 7 additions & 0 deletions test/static/required.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,10 @@ import * as Types from '@sinclair/typebox'
})]))
Expect(T).ToStatic<number | { x: number }>
}
// prettier-ignore
{
const T = Type.Required(Type.Union([Type.Literal(1), Type.Object({
x: Type.Optional(Type.Number())
})]))
Expect(T).ToStatic<1 | { x: number }>
}

0 comments on commit fca9f0d

Please sign in to comment.