You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi! I'm trying to integrate TypeBox into an existing TypeScript codebase, as a much more robust alternative to value is T predicate functions. But I'm having trouble getting things to type-check properly, because I want to maintain the existing generic types as much as possible.
The TypeBox docs say to use T extends TSchema for your generic type parameters, and the Workbench produces code that does this. But if my regular TypeScript type looks like this:
Which "forgets" the extends string condition on TType, and also requires references to the type to be written something like EventDTOBase<TString, TData> rather than EventDTOBase<string, Data>. Since I'm not actually going to be serialising or validating many of the types in the system, having to use TypeBox's types for all of them isn't ideal.
So I've been experimenting with this approach, which expects regular TypeScript types as the type-level parameters and then TypeBox schemas as the value-level parameters:
/** Static<T>, except that it works on generics too. This part works fine. :) */exporttypeUnboxed<T>=TextendsTSchema ? Static<T>
: Textends(...args: unknown[])=>TSchema ? Static<ReturnType<T>>
: never;/** Theoretically the inverse of Static<T>, turning a regular TypeScript type into a static schema type matching up with it. This part does not work. */exporttypeBoxed<T>=TextendsStatic<infer UextendsTSchema> ? U : never;exporttypeEventDTOBase<TTypeextendsstring,TData>=Unboxed<typeofEventDTOBaseSchema<TType,TData>>;exportconstEventDTOBaseSchema<TTypeextendsstring,TData>=(TType: Boxed<TType>,TData: Boxed<TData>)=>Type.Object({source_type: TType,source_key: Type.String(),source_subkey: Type.Union([Type.String(),Type.Null()]),data: TData});
However TypeScript doesn't seem to be quite clever enough to infer the schema type from Boxed<T>, which isn't surprising since Static<T> is basically just T['static']. I also tried just making the function arguments (TType: TSchema, TData: TSchema), but the inference still struggled and it couldn't type the return value correctly even if that worked.
So, is there a way to derive schema types from regular TypeScript types in-language? I don't need to actually generate the runtime schema, and I'm aware TypeScript wouldn't let you do that anyway due to type erasure - I just need a way to write "given type T, give me type U such that Static<U> = T" at the type level.
Or, possibly, a different approach entirely to writing generic types compatible with TypeBox. Is there a technique I'm missing, maybe?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi! I'm trying to integrate TypeBox into an existing TypeScript codebase, as a much more robust alternative to
value is T
predicate functions. But I'm having trouble getting things to type-check properly, because I want to maintain the existing generic types as much as possible.The TypeBox docs say to use
T extends TSchema
for your generic type parameters, and the Workbench produces code that does this. But if my regular TypeScript type looks like this:Then TypeBox's workbench will turn that into:
Which "forgets" the
extends string
condition onTType
, and also requires references to the type to be written something likeEventDTOBase<TString, TData>
rather thanEventDTOBase<string, Data>
. Since I'm not actually going to be serialising or validating many of the types in the system, having to use TypeBox's types for all of them isn't ideal.So I've been experimenting with this approach, which expects regular TypeScript types as the type-level parameters and then TypeBox schemas as the value-level parameters:
However TypeScript doesn't seem to be quite clever enough to infer the schema type from
Boxed<T>
, which isn't surprising sinceStatic<T>
is basically justT['static']
. I also tried just making the function arguments(TType: TSchema, TData: TSchema)
, but the inference still struggled and it couldn't type the return value correctly even if that worked.So, is there a way to derive schema types from regular TypeScript types in-language? I don't need to actually generate the runtime schema, and I'm aware TypeScript wouldn't let you do that anyway due to type erasure - I just need a way to write "given type
T
, give me typeU
such thatStatic<U> = T
" at the type level.Or, possibly, a different approach entirely to writing generic types compatible with TypeBox. Is there a technique I'm missing, maybe?
Beta Was this translation helpful? Give feedback.
All reactions