Skip to content

Commit

Permalink
Recursive Fix: Evaluate Record and Array (#735)
Browse files Browse the repository at this point in the history
* Fix some infinite recursion with static types

* Adds test for #336

* Fix import path

* Rename unused type parameter
  • Loading branch information
ghalle authored Jan 21, 2024
1 parent cc06871 commit 28164b1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
8 changes: 5 additions & 3 deletions src/type/array/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import type { TSchema, SchemaOptions } from '../schema/index'
import { CloneType } from '../clone/type'
import { Ensure } from '../helpers/index'
import type { SchemaOptions, TSchema } from '../schema/index'
import type { Static } from '../static/index'
import { Kind } from '../symbols/index'
import { CloneType } from '../clone/type'

export interface ArrayOptions extends SchemaOptions {
/** The minimum number of items in this array */
Expand All @@ -45,9 +46,10 @@ export interface ArrayOptions extends SchemaOptions {
/** A maximum number of contains schema matches */
maxContains?: number
}
type ArrayStatic<T extends TSchema, P extends unknown[]> = Ensure<Static<T, P>[]>
export interface TArray<T extends TSchema = TSchema> extends TSchema, ArrayOptions {
[Kind]: 'Array'
static: Array<Static<T, this['params']>>
static: ArrayStatic<T, this['params']>
type: 'array'
items: T
}
Expand Down
2 changes: 1 addition & 1 deletion src/type/record/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function FromNumberKey<K extends TNumber, T extends TSchema>(_: K, T: T, options
// ------------------------------------------------------------------
// prettier-ignore
type RecordStatic<K extends TSchema, T extends TSchema, P extends unknown[]> = (
Evaluate<Record<Assert<Static<K>, PropertyKey>, Static<T, P>>>
Evaluate<{ [_ in Assert<Static<K>, PropertyKey>]: Static<T, P>; }>
)
// prettier-ignore
export interface TRecord<K extends TSchema = TSchema, T extends TSchema = TSchema> extends TSchema {
Expand Down
23 changes: 22 additions & 1 deletion test/static/recursive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Static, Type } from '@sinclair/typebox'
import { Expect } from './assert'
import { Type, Static } from '@sinclair/typebox'

{
// identity
Expand Down Expand Up @@ -78,3 +78,24 @@ import { Type, Static } from '@sinclair/typebox'
nodes: Static<typeof T>[]
}>()
}
{
// issue: https://github.com/sinclairzx81/typebox/issues/336
type JSONValue =
| string
| number
| null
| boolean
| { [x: string]: JSONValue }
| JSONValue[]
const R = Type.Recursive((Node) =>
Type.Union([
Type.Null(),
Type.String(),
Type.Number(),
Type.Boolean(),
Type.Record(Type.String(), Node),
Type.Array(Node),
]),
)
Expect(R).ToStatic<JSONValue>()
}

0 comments on commit 28164b1

Please sign in to comment.