deno.land / x / typebox@0.32.21 / changelog / 0.29.2.md

0.29.2

Overview

Revision 0.29.2 includes enhancements to Type.Index

This revision contains no breaking changes

Contents

Modifier Index Resolver

Revision 0.29.2 re-introduces optional property narrowing for Indexed Access Types. This functionality is specific when indexing overlapping properties with one or more optional modifiers. Revision 0.28.0 attempted to implement this narrowing, however was pulled due to instantiation issues raised on issue 419 (specific to composite narrowing)

Revision 0.29.2 attempts to re-introduce this functionality using a different resolution strategy. It uses Indexed Access Types as the construct in which to apply such narrowing and expands upon Union and Intersection type normalization for optional modifier unwrap and remapping. This approach unifies Composite inference with Index Access Types and makes provisions for a possible Type.Mapped feature in later releases.

Indexed Intersect

The following are the index resolver cases for intersect types.

Case 1

const T = Type.Intersect([
  Type.Object({ x: Type.Optional(Type.Number()) }),
  Type.Object({ x: Type.Optional(Type.Number()) })
])

const I = Type.Index(T, ['x']) 

// type I = TOptional<TUnion<[TNumber, TNumber]>>

Case 2

const T = Type.Intersect([
  Type.Object({ x: Type.Optional(Type.Number()) }),
  Type.Object({ x: Type.Number() })
])

const I = Type.Index(T, ['x']) 

// type I = TUnion<[TNumber, TNumber]>

Case 3

const T = Type.Intersect([
  Type.Object({ x: Type.Number() }),
  Type.Object({ x: Type.Number() })
])

const I = Type.Index(T, ['x']) 

// type I = TUnion<[TNumber, TNumber]>

Indexed Union

The following are the index resolver cases for union types.

Case 1

const T = Type.Union([
  Type.Object({ x: Type.Optional(Type.Number()) }),
  Type.Object({ x: Type.Optional(Type.Number()) })
])

const I = Type.Index(T, ['x']) 

// type I = TOptional<TUnion<[TNumber, TNumber]>>

Case 2

const T = Type.Union([
  Type.Object({ x: Type.Optional(Type.Number()) }),
  Type.Object({ x: Type.Number() })
])

const I = Type.Index(T, ['x']) 

// type I = TOptional<TUnion<[TNumber, TNumber]>>

Case 3

const T = Type.Union([
  Type.Object({ x: Type.Number() }),
  Type.Object({ x: Type.Number() })
])

const I = Type.Index(T, ['x']) 

// type I = TUnion<[TNumber, TNumber]>

Composite

The following are the resolver cases for indexed types when applied to composite intersection.

Case 1

const T = Type.Composite([
  Type.Object({ x: Type.Optional(Type.Number()) }),
  Type.Object({ x: Type.Optional(Type.Number()) })
])

// type T = TObject<{
//    x: TOptional<TUnion<[TNumber, TNumber]>>
// }>

Case 2

const T = Type.Composite([
  Type.Object({ x: Type.Optional(Type.Number()) }),
  Type.Object({ x: Type.Number() })
])

// type T = TObject<{
//   x: TUnion<[TNumber, TNumber]>
// }>

Case 3

const T = Type.Composite([
  Type.Object({ x: Type.Number() }),
  Type.Object({ x: Type.Number() })
])

// type T = TObject<{
//   x: TUnion<[TNumber, TNumber]>
// }>
typebox

Version Info

Tagged at
3 weeks ago