Replies: 3 comments
-
Hi, I'm having the same problem as you. |
Beta Was this translation helpful? Give feedback.
-
TypeBox doesn't apply the readOnly annotation by default. The reasons for this are largely historical and mostly due to how TypeBox internally handles inference and type differentiation, however you can apply the annotation in the following way. import { Type, TSchema, TReadonly } from '@sinclair/typebox'
function ReadonlyWithAnnotation<T extends TSchema>(schema: T): TReadonly<T> {
return Type.Readonly({ ...schema, readOnly: true }) as never
}
const T = Type.Object({
x: ReadonlyWithAnnotation(Type.Number())
}) I've been meaning to take another look into this, but wouldn't be able to make any changes until a minor semver revision (this due to the addition of the Hope this helps |
Beta Was this translation helpful? Give feedback.
-
@sdc395 Sorry, just to respond to your original comment...
The Type.Readonly modifier is representative of the ReadonlyDeepYou can however implement the TS utility type in the following way (TypeBox may provide this type in future (just need a reasonable name for it)) import * as Type from '@sinclair/typebox'
// ------------------------------------------------------------------
// ReadonlyProperties
// ------------------------------------------------------------------
export type TReadonlyProperties<T extends Type.TProperties> = Type.Evaluate<{
[K in keyof T]: TReadonlyDeep<T[K]>
}>
function ReadonlyProperties<T extends Type.TProperties>(properties: T) {
return globalThis.Object.getOwnPropertyNames(properties).reduce((Acc, K) => {
return { ...Acc, [K]: ReadonlyDeep(properties[K]) }
}, {})
}
// ------------------------------------------------------------------
// ReadonlyRest
// ------------------------------------------------------------------
export type TReadonlyRest<T extends Type.TSchema[], Acc extends Type.TSchema[] = []> = (
T extends [infer L extends Type.TSchema, ...infer R extends Type.TSchema[]]
? TReadonlyRest<R, [...Acc, TReadonlyDeep<L>]>
: Acc
)
function ReadonlyRest<T extends Type.TSchema[]>(schema: [...T]): TReadonlyRest<T> {
return schema.map(schema => ReadonlyDeep(schema)) as never
}
// ------------------------------------------------------------------
// ReadonlyDeep
// ------------------------------------------------------------------
export type TReadonlyDeep<T extends Type.TSchema> =
T extends Type.TIntersect<infer S extends Type.TSchema[]> ? Type.TReadonly<Type.TIntersect<TReadonlyRest<S>>> :
T extends Type.TUnion<infer S extends Type.TSchema[]> ? Type.TReadonly<Type.TUnion<TReadonlyRest<S>>> :
T extends Type.TTuple<infer S extends Type.TSchema[]> ? Type.TReadonly<Type.TUnion<TReadonlyRest<S>>> :
T extends Type.TObject<infer S extends Type.TProperties> ? Type.TReadonly<Type.TObject<TReadonlyProperties<S>>> :
T extends Type.TArray<infer S extends Type.TSchema> ? Type.TReadonly<Type.TArray<TReadonlyDeep<S>>> :
Type.TReadonly<T>
function ReadonlyDeep<T extends Type.TSchema>(schema: T): TReadonlyDeep<T> {
return (
Type.TypeGuard.IsIntersect(schema) ? Type.Readonly(Type.Intersect(ReadonlyRest(schema.allOf))) :
Type.TypeGuard.IsUnion(schema) ? Type.Readonly(Type.Union(ReadonlyRest(schema.anyOf))) :
Type.TypeGuard.IsObject(schema) ? Type.Readonly(Type.Object(ReadonlyProperties(schema.properties))) :
Type.TypeGuard.IsArray(schema) ? Type.Readonly(Type.Array(ReadonlyDeep(schema.items))) :
Type.Readonly(schema)
) as never
}
// ------------------------------------------------------------------
// Example
// ------------------------------------------------------------------
const T = ReadonlyDeep(Type.Object({
x: Type.Number(),
y: Type.Object({
z: Type.Number()
})
}))
type T = Type.Static<typeof T> In the nearer term, I may consider adding the above as a prototype for inclusion in later revisions. Hope this brings some insight |
Beta Was this translation helpful? Give feedback.
-
Hi all
Just wondering why the following does not infer a read-only type.
I know I can add
Type.Readonly
to each property, but it would be much more convenient ifType.Readonly
would produce the expected type (or complain about being given aTSchema
).For now, I use
type S = Readonly<Static<typeof T>>;
. Perhaps that's the intended approach.Beta Was this translation helpful? Give feedback.
All reactions