Skip to content

Commit e9d9fa0

Browse files
authored
Version 1.0.46 (#1432)
* Readonly * ChangeLog * Version
1 parent 4a62032 commit e9d9fa0

25 files changed

Lines changed: 740 additions & 36 deletions

changelog/1.0.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
---
44

55
### Version Updates
6+
- [Revision 1.0.46](https://github.com/sinclairzx81/typebox/pull/1432)
7+
- Add ReadonlyType Utility Type (mirroring TypeScript `Readonly<T>`)
68
- [Revision 1.0.45](https://github.com/sinclairzx81/typebox/pull/1431)
79
- Fix for Codec Inference. Prevent Recursive `~codec` keyword matching.
810
- [Revision 1.0.44](https://github.com/sinclairzx81/typebox/pull/1420)

design/website/docs/type/partial.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
# Partial
22

3-
Makes all properties of an Object optional.
3+
This type is an alias for the `Partial<T>` TypeScript utility type. It makes all properties of an Object optional.
44

55
## Example
66

77
Example usage is shown below.
88

99
```typescript
10-
const T = Type.Object({ // const T = {
11-
x: Type.Number(), // type: 'object',
12-
y: Type.Number(), // required: ['x', 'y', 'z'],
13-
z: Type.Number() // properties: {
14-
}) // x: { type: 'number' },
15-
// y: { type: 'number' },
16-
// z: { type: 'number' }
17-
// }
18-
// }
10+
const T = Type.Object({ // const T: TObject<{
11+
x: Type.Number(), // x: TNumber,
12+
y: Type.Number(), // y: TNumber,
13+
z: Type.Number() // z: TNumber
14+
}) // }>
1915

2016
const S = Type.Partial(T) // const S: TObject<{
2117
// x: TOptional<TNumber>,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ReadonlyType
2+
3+
This type is an alias for the `Readonly<T>` TypeScript utility type. It makes all properties of an Object `readonly` or marks an Array or Tuple as immutable `readonly T[]`.
4+
5+
## Example
6+
7+
When applied to a Object, each property of the Object will be marked as `TReadonly<T>`
8+
9+
```typescript
10+
const T = Type.Object({ // const T = TObject<{
11+
x: Type.Number(), // x: TNumber,
12+
y: Type.Number(), // y: TNumber,
13+
z: Type.Number() // z: TNumber,
14+
}) // }>
15+
16+
const S = Type.ReadonlyType(T) // const S: TObject<{
17+
// x: TReadonly<TNumber>,
18+
// y: TReadonly<TNumber>,
19+
// z: TReadonly<TNumber>
20+
// }>
21+
```
22+
23+
When applied to an Array or Tuple, the type is marked as `TImmutable<T>`
24+
25+
```typescript
26+
const T = Type.Tuple([ // const T = TImmutable<TTuple<[
27+
Type.Number(), // TNumber,
28+
Type.String(), // TString
29+
]) // ]>>
30+
31+
const S = Type.ReadonlyType(T) // const S: TImmutable<TTuple<[
32+
// TNumber,
33+
// TString
34+
// }>>
35+
36+
type S = Type.Static<typeof S> // type S = readonly [number, string]
37+
```

docs/docs/type/partial.html

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
<h1>Partial</h1>
2-
<p>Makes all properties of an Object optional.</p>
2+
<p>This type is an alias for the <code>Partial&lt;T&gt;</code> TypeScript utility type. It makes all properties of an Object optional.</p>
33
<h2>Example</h2>
44
<p>Example usage is shown below.</p>
5-
<pre><code class="language-typescript">const T = Type.Object({ // const T = {
6-
x: Type.Number(), // type: &#39;object&#39;,
7-
y: Type.Number(), // required: [&#39;x&#39;, &#39;y&#39;, &#39;z&#39;],
8-
z: Type.Number() // properties: {
9-
}) // x: { type: &#39;number&#39; },
10-
// y: { type: &#39;number&#39; },
11-
// z: { type: &#39;number&#39; }
12-
// }
13-
// }
5+
<pre><code class="language-typescript">const T = Type.Object({ // const T: TObject&lt;{
6+
x: Type.Number(), // x: TNumber,
7+
y: Type.Number(), // y: TNumber,
8+
z: Type.Number() // z: TNumber
9+
}) // }&gt;
1410

1511
const S = Type.Partial(T) // const S: TObject&lt;{
1612
// x: TOptional&lt;TNumber&gt;,

docs/docs/type/readonly-type.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<h1>ReadonlyType</h1>
2+
<p>This type is an alias for the <code>Readonly&lt;T&gt;</code> TypeScript utility type. It makes all properties of an Object <code>readonly</code> or marks an Array or Tuple as immutable <code>readonly T[]</code>.</p>
3+
<h2>Example</h2>
4+
<p>When applied to a Object, each property of the Object will be marked as <code>TReadonly&lt;T&gt;</code></p>
5+
<pre><code class="language-typescript">const T = Type.Object({ // const T = TObject&lt;{
6+
x: Type.Number(), // x: TNumber,
7+
y: Type.Number(), // y: TNumber,
8+
z: Type.Number() // z: TNumber,
9+
}) // }&gt;
10+
11+
const S = Type.ReadonlyType(T) // const S: TObject&lt;{
12+
// x: TReadonly&lt;TNumber&gt;,
13+
// y: TReadonly&lt;TNumber&gt;,
14+
// z: TReadonly&lt;TNumber&gt;
15+
// }&gt;
16+
</code></pre>
17+
<p>When applied to an Array or Tuple, the type is marked as <code>TImmutable&lt;T&gt;</code></p>
18+
<pre><code class="language-typescript">const T = Type.Tuple([ // const T = TImmutable&lt;TTuple&lt;[
19+
Type.Number(), // TNumber,
20+
Type.String(), // TString
21+
]) // ]&gt;&gt;
22+
23+
const S = Type.ReadonlyType(T) // const S: TImmutable&lt;TTuple&lt;[
24+
// TNumber,
25+
// TString
26+
// }&gt;&gt;
27+
28+
type S = Type.Static&lt;typeof S&gt; // type S = readonly [number, string]
29+
</code></pre>

docs/manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"partial": "docs/type/partial.html",
103103
"pick": "docs/type/pick.html",
104104
"promise": "docs/type/promise.html",
105+
"readonly-type": "docs/type/readonly-type.html",
105106
"readonly": "docs/type/readonly.html",
106107
"record": "docs/type/record.html",
107108
"ref": "docs/type/ref.html",

src/type/action/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export * from './options.ts'
4848
export * from './parameters.ts'
4949
export * from './partial.ts'
5050
export * from './pick.ts'
51+
export * from './readonly-type.ts'
5152
export * from './required.ts'
5253
export * from './return-type.ts'
5354
export * from './uncapitalize.ts'

src/type/action/readonly-type.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*--------------------------------------------------------------------------
2+
3+
TypeBox
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) 2017-2025 Haydn Paterson
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
---------------------------------------------------------------------------*/
28+
29+
// deno-fmt-ignore-file
30+
31+
import { type TSchema, type TSchemaOptions } from '../types/schema.ts'
32+
import { type TDeferred, Deferred } from '../types/deferred.ts'
33+
import { type TInstantiate, Instantiate } from '../engine/instantiate.ts'
34+
35+
// ------------------------------------------------------------------
36+
// Deferred
37+
// ------------------------------------------------------------------
38+
/** Creates a deferred ReadonlyType action. */
39+
export type TReadonlyTypeDeferred<Type extends TSchema> = (
40+
TDeferred<'ReadonlyType', [Type]>
41+
)
42+
/** Creates a deferred ReadonlyType action. */
43+
export function ReadonlyTypeDeferred<Type extends TSchema>(type: Type, options: TSchemaOptions = {}) {
44+
return Deferred('ReadonlyType', [type], options)
45+
}
46+
// ------------------------------------------------------------------
47+
// Type
48+
// ------------------------------------------------------------------
49+
/** This type is an alias for the TypeScript `Readonly<T>` utility type. */
50+
export type TReadonlyType<Type extends TSchema> = (
51+
TInstantiate<{}, TReadonlyTypeDeferred<Type>>
52+
)
53+
/** This type is an alias for the TypeScript `Readonly<T>` utility type. */
54+
export function ReadonlyType<Type extends TSchema>(type: Type, options: TSchemaOptions = {}): TReadonlyType<Type> {
55+
return Instantiate({}, ReadonlyTypeDeferred(type, options)) as never
56+
}

src/type/engine/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export * from './parameters/index.ts'
5858
export * from './patterns/index.ts'
5959
export * from './partial/index.ts'
6060
export * from './pick/index.ts'
61+
export * from './readonly-type/index.ts'
6162
export * from './record/index.ts'
6263
export * from './ref/index.ts'
6364
export * from './required/index.ts'

src/type/engine/instantiate.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ import { type TOptionsInstantiate, OptionsInstantiate } from './options/instanti
9090
import { type TParametersInstantiate, ParametersInstantiate } from './parameters/instantiate.ts'
9191
import { type TPartialInstantiate, PartialInstantiate } from './partial/instantiate.ts'
9292
import { type TPickInstantiate, PickInstantiate } from './pick/instantiate.ts'
93+
import { type TReadonlyTypeInstantiate, ReadonlyTypeInstantiate } from './readonly-type/instantiate.ts'
9394
import { type TRecordInstantiate, RecordInstantiate } from './record/instantiate.ts'
9495
import { type TRefInstantiate, RefInstantiate } from './ref/instantiate.ts'
9596
import { type TRequiredInstantiate, RequiredInstantiate } from './required/instantiate.ts'
@@ -288,6 +289,7 @@ type TInstantiateDeferred<Context extends TProperties, State extends TState, Act
288289
[Action, Parameters] extends ['Parameters', [infer Type extends TSchema]] ? TParametersInstantiate<Context, State, Type> :
289290
[Action, Parameters] extends ['Partial', [infer Type extends TSchema]] ? TPartialInstantiate<Context, State, Type> :
290291
[Action, Parameters] extends ['Omit', [infer Type extends TSchema, infer Indexer extends TSchema]] ? TOmitInstantiate<Context, State, Type, Indexer> :
292+
[Action, Parameters] extends ['ReadonlyType', [infer Type extends TSchema]] ? TReadonlyTypeInstantiate<Context, State, Type> :
291293
[Action, Parameters] extends ['Record', [infer Key extends TSchema, infer Value extends TSchema]] ? TRecordInstantiate<Context, State, Key, Value> :
292294
[Action, Parameters] extends ['Required', [infer Type extends TSchema]] ? TRequiredInstantiate<Context, State, Type> :
293295
[Action, Parameters] extends ['ReturnType', [infer Type extends TSchema]] ? TReturnTypeInstantiate<Context, State, Type> :
@@ -320,6 +322,7 @@ function InstantiateDeferred<Context extends TProperties, State extends TState,
320322
Guard.IsEqual(action, 'Parameters') ? ParametersInstantiate(context, state, parameters[0], options) :
321323
Guard.IsEqual(action, 'Partial') ? PartialInstantiate(context, state, parameters[0], options) :
322324
Guard.IsEqual(action, 'Omit') ? OmitInstantiate(context, state, parameters[0], parameters[1], options) :
325+
Guard.IsEqual(action, 'ReadonlyType') ? ReadonlyTypeInstantiate(context, state, parameters[0], options) :
323326
Guard.IsEqual(action, 'Record') ? RecordInstantiate(context, state, parameters[0], parameters[1], options) :
324327
Guard.IsEqual(action, 'Required') ? RequiredInstantiate(context, state, parameters[0], options) :
325328
Guard.IsEqual(action, 'ReturnType') ? ReturnTypeInstantiate(context, state, parameters[0], options) :

0 commit comments

Comments
 (0)