String to literal after parse #716
-
First of all thank you for the great library! Tried zod but typebox is a lot better for my use cases. Please take a look at this example: We have base schema const BaseComponentSchema = Type.Object({
type: Type.String(),
id: Type.String(),
name: Type.String(),
}); And we have a method CreateComponentSchema this method should return ComponentSchema but type and id should be literals. This will work /**
* @template {string} T
* @template {string} B
* @param {object} config
* @param {T} config.id
* @param {B} config.type
*/
const CreateComponentSchema = (config) => {
return Type.Composite([
BaseComponentSchema,
Type.Object({
id: Type.Literal(config.id),
type: Type.Literal(config.type),
}),
]);
};
const TestComponentSchema = CreateComponentSchema({
id: 'test',
type: 'asdasd',
});
/**@typedef {import('@sinclair/typebox').Static<typeof TestComponentSchema>} TestComponent */
// {id: 'test'...} we would like to validate config first but if we are using unknown there is no way anymore to infer string value as literal, right? /**
* @param {unknown} config
*/
const CreateComponentSchema = (config) => {
const check = Check(BaseComponentSchema, config);
if (!check)
throw new Error(Errors(BaseComponentSchema, config)?.First()?.message);
const parsedConfig = /**@type {import('@sinclair/typebox').Static<typeof BaseComponentSchema>}*/ (config);
return Type.Composite([
BaseComponentSchema,
Type.Object({
id: Type.Literal(parsedConfig.id),
type: Type.Literal(parsedConfig.type),
}),
]);
};
const TestComponentSchema = CreateComponentSchema({
id: 'test',
type: 'asdasd',
});
/**@typedef {import('@sinclair/typebox').Static<typeof TestComponentSchema>} TestComponent */
// {id: string...} Thanks a lot in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
@alexey13 Hi, Try the following import { Type, Static } from '@sinclair/typebox'
// ... Base
const BaseComponentSchema = Type.Object({
type: Type.String(),
id: Type.String(),
name: Type.String(),
})
// ... Component
// Create config type which uses generic arguments for each property.
interface CreateComponentSchemaConfig<Type = string, Id = string> {
id: Id
type: Type,
}
const CreateComponentSchema = <Type extends string, Id extends string>(config: CreateComponentSchemaConfig<Type, Id>) => {
return Type.Composite([
BaseComponentSchema,
Type.Object({
id: Type.Literal(config.id),
type: Type.Literal(config.type),
}),
]);
};
// ... Usage
const T = CreateComponentSchema({
id: 'test',
type: 'asdasd',
})
type T = Static<typeof T> The trick is encoding the string literals as generic arguments for the Hope this helps |
Beta Was this translation helpful? Give feedback.
@alexey13 Hi, Try the following
TypeScript Link Here