mirror of
https://github.com/zoriya/typebox.git
synced 2026-05-24 23:45:32 +00:00
Revision 0.29.1
This commit is contained in:
+40
-4
@@ -6,6 +6,15 @@ Revision 0.29.0 makes a minor interface and schema representation change to the
|
||||
|
||||
As this revision constitutes a breaking representation change for `Type.Not`, a minor semver revision is required.
|
||||
|
||||
## Contents
|
||||
|
||||
- Enhancements
|
||||
- [Type.Not Representation Change](#Representation-Change)
|
||||
- [Not Inversion](#Not-Inversion)
|
||||
- [Inference Limitations](#Inference-Limitations)
|
||||
|
||||
<a name="Representation-Change"></a>
|
||||
|
||||
## Type.Not Representation Change
|
||||
|
||||
The `Type.Not` was first introduced in Revision 0.26.0. This type accepted two arguments, the first is the `not` type, the second is the `allowed` type. In 0.26.0, TypeBox would treat the `allowed` type as the inferred type with the schema represented in the following form.
|
||||
@@ -81,11 +90,13 @@ const T = {
|
||||
//
|
||||
type T = Static<typeof T> // type T = number
|
||||
```
|
||||
The 0.29.0 `Not` type properly represents the JSON Schema `not` keyword in its simplest form, as well as making better use of the type intersection narrowing capabilities of TypeScript with respect to inference.
|
||||
The 0.29.0 `Not` type properly represents the JSON Schema `not` keyword in its simplest form, as well as making better use of intersection type narrowing capabilities of TypeScript.
|
||||
|
||||
### Invert Not
|
||||
<a name="Not-Inversion"></a>
|
||||
|
||||
In revision 0.29.0, it is possible to invert the `Not` type. TypeBox will track each inversion and statically infer appropriately.
|
||||
## Not Inversion
|
||||
|
||||
The not type can be inverted through nesting.
|
||||
|
||||
```typescript
|
||||
// not not string
|
||||
@@ -105,4 +116,29 @@ const T = {
|
||||
// inferred as
|
||||
//
|
||||
type T = Static<typeof T> // type T = string
|
||||
```
|
||||
```
|
||||
|
||||
<a name="Inference-Limitations"></a>
|
||||
|
||||
## Inference Limitations
|
||||
|
||||
Not types are synonymous with the concept of [negated types](https://github.com/microsoft/TypeScript/issues/4196) which are not supported in the TypeScript language. Because of this, it is not currently possible to infer negated types in a way one would naturally expect for some cases. Consider the following.
|
||||
|
||||
```typescript
|
||||
const T = Type.Intersect([Type.String(), Type.Not(Type.String())])
|
||||
|
||||
type T = Static<typeof T> // type T = string & not string
|
||||
// actual: string
|
||||
// expect: never
|
||||
```
|
||||
As such, the use of Not types should be used with some consideration to current limitations, and reserved primarily for narrowing cases such as the following.
|
||||
|
||||
```typescript
|
||||
const T = Type.Intersect([Type.String(), Type.Not(Type.Literal('disallowed string'))])
|
||||
|
||||
type T = Static<typeof T> // type T = string & not 'disallowed string'
|
||||
// actual: string
|
||||
// expect: string
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -888,14 +888,16 @@ const C = Type.Index(T, Type.KeyOf(T)) // const C = {
|
||||
|
||||
### Not Types
|
||||
|
||||
Not types are supported with `Type.Not`. This type represents the JSON Schema `not` keyword and will statically infer as `unknown`. Note that Not types are not supported in TypeScript, but can still be partially expressed by interpreting `not` as the broad type `unknown`. When used in intersections, the Not type can be used to create refined assertion rules for specific types, with the inference derived from TypeScript's ability to narrow from `unknown` to `T` via intersection.
|
||||
|
||||
For example, consider a type which is `number` but not `1 | 2 | 3` and where the static type would still technically be a `number`. The following shows a pseudo TypeScript example using `not` followed by the TypeBox implementation.
|
||||
TypeBox has partial support for the JSON schema `not` keyword with `Type.Not`. This type is synonymous with the concept of a [negated types](https://github.com/microsoft/TypeScript/issues/4196) which are not supported in the TypeScript language. TypeBox does provide partial inference support via the intersection of `T & not U` (where all negated types infer as `unknown`). This can be used in the following context.
|
||||
|
||||
```typescript
|
||||
// Pseudo TypeScript
|
||||
// TypeScript
|
||||
|
||||
type T = number & not (1 | 2 | 3) // allow all numbers except 1, 2, 3
|
||||
type T = Exclude<number, 1 | 2 | 3> // all numbers except 1, 2, 3
|
||||
//
|
||||
// ideally expressed as:
|
||||
//
|
||||
// type T = number & not (1 | 2 | 3)
|
||||
|
||||
// TypeBox
|
||||
|
||||
@@ -914,11 +916,11 @@ const T = Type.Intersect([ // const T = {
|
||||
// ]
|
||||
// }
|
||||
|
||||
type T = Static<typeof T> // evaluates as:
|
||||
type T = Static<typeof T> // inferred:
|
||||
//
|
||||
// type T = (number & (not (1 | 2 | 3)))
|
||||
// type T = (number & (unknown))
|
||||
// type T = (number)
|
||||
// type T = number & not (1 | 2 | 3)
|
||||
// type T = number & unknown
|
||||
// type T = number
|
||||
```
|
||||
|
||||
The Not type can be used with constraints to define schematics for types that would otherwise be difficult to express.
|
||||
|
||||
Reference in New Issue
Block a user