From 0af35f4a334c9b78db28684685a5014df211b925 Mon Sep 17 00:00:00 2001 From: sinclairzx81 Date: Tue, 6 Jul 2021 18:41:28 +0900 Subject: [PATCH] Adding changelog.md --- changelog.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ example/index.ts | 16 +++----- 2 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..8c94295 --- /dev/null +++ b/changelog.md @@ -0,0 +1,98 @@ + + +## [0.17.6](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.6) + +- Added `Type.Rec(...)` function. + +This update introduces the `Type.Rec()` function for enabling Recursive Types. This feature is enabled without support for static inference of the recursive type. This is due to current inference limitations around TypeScript recursive types. The `Self` argument passed on `Type.Rec(Self => ...)` is a `TAny` and will statically resolve to type `any`. Callers can optionally type assert if nessasary. + +```typescript +const Operator = Type.Union([ + Type.Literal('+'), + Type.Literal('-'), + Type.Literal('/'), + Type.Literal('*') +]) + +type Expression = Static + +// Defines a self referencing type. +const Expression = Type.Rec(Self => Type.Object({ + left: Type.Union([Self, Type.Number()]), + right: Type.Union([Self, Type.Number()]), + operator: Operator +})) + +function evaluate(expression: Expression): number { + const left = typeof expression.left !== 'number' + ? evaluate(expression.left as Expression) // assert as Expression + : expression.left + const right = typeof expression.right !== 'number' + ? evaluate(expression.right as Expression) // assert as Expression + : expression.right + switch(expression.operator) { + case '+': return left + right + case '-': return left - right + case '*': return left * right + case '/': return left / right + } +} + +const result = evaluate({ + left: { + left: 10, + operator: '*', + right: 4, + }, + operator: '+', + right: 2, +}) // -> 42 +``` + +This functionality is flagged as `EXPERIMENTAL` and awaits community feedback. + +## [0.17.4](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.4) + +- Added `Type.Box()` and `Type.Ref()` functions. + +This update provides the `Type.Box()` function to enable common related schemas to grouped under a common namespace; typically expressed as a `URI`. This functionality is primarily geared towards allowing one to define a common set of domain objects that may be shared across application domains running over a network. The `Type.Box()` is intended to be an analog to `XML` `xmlns` namespacing. + +The `Type.Ref()` function is limited to referencing from boxes only. The following is an example. + +```typescript +// Domain objects for the fruit service. +const Fruit = Type.Box('https://fruit.domain.com', { + Apple: Type.Object({ ... }), + Orange: Type.Object({ ... }), +}) + +// An order referencing types of the fruit service. +const Order = Type.Object({ + id: Type.String(), + quantity: Type.Number(), + item: Type.Union([ + Type.Ref(Fruit, 'Apple'), + Type.Ref(Fruit, 'Orange') + ]) +}) +``` + +Currently, `Type.Omit()`, `Type.Pick()`, `Type.Partial()`, `Type.Readonly()` and `Type.Intersect()` do not work with Reference Types. This may change in later revisions. + +This functionality is flagged as `EXPERIMENTAL` and awaits community feedback. + +## [0.17.1](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.1) + +- Remove default `additionalProperties: false` constraint from all object schemas. + +This update removes the `additionalProperties: false` constraint on all object schemas. This constraint was introduced on `0.16.x` but has resulted in significant downstream problems composing schemas whose types `intersect`. This is due to a JSON schema design principle where constraints should only be added (never removed), and that intersection types may require removal of the `additionalProperties` constraint in some cases, this had resulted in some ambiguity with respect to how TypeBox should handle such intersections. + +This update can also be seen as a precursor towards TypeBox potentially leveraging `unevaluatedProperties` for type intersection in future releases. Implementors should take note that in order to constrain the schema to known properties, one should apply the `additionalProperties: false` as the second argument to `Type.Object({...})`. + +```typescript +const T = Type.Object({ + a: Type.String(), + b: Type.Number() +}, { + additionalProperties: false +}) \ No newline at end of file diff --git a/example/index.ts b/example/index.ts index d086460..4c2b8b8 100644 --- a/example/index.ts +++ b/example/index.ts @@ -1,14 +1,10 @@ import { Type, Static } from '@sinclair/typebox' -type Node = Static +const Box = Type.Box('foo', { + Foo: Type.String() +}) -const Node = Type.Rec(Self => Type.Object({ - id: Type.String(), - nodes: Type.Array(Self) -})) +const Foo = Type.Ref(Box, 'Foo') + +type Foo = Static -function walk(node: Node) { - for(const inner of node.nodes) { - walk(inner as Node) - } -}