I need help!
I'm trying to create a Schema
definition Type
based on a Type
given by user. The problem here is when I try to create a Type
that must be one of the value of an Array, the Schema
definition type is not working as expected.
For example, I have a user object and I need the value of the status
is an Enum
, which either verified
or created
. When defining the schema, I also need to make sure that the type
property is enum
and I have to define the enums
property which have all of the possible status (['verified', 'created']
).
My Schema
definition Type
is:
type Enum<T> = T;
// To convert typescript's type into string.
type TypeOf<T> = T extends object
? 'object'
: T extends Enum<unknown>
? 'enum'
: 'string';
// Schema definition is dynamic, based on the given T.
type Schema<T> = T extends object
? ObjectSchema<T>
: T extends Enum<unknown>
? EnumSchema<T>
: BaseSchema<T>;
type BaseSchema<T> = {
type: TypeOf<T>; // Make sure the type value is a correct type.
default?: T;
}
// When the given T is an Object.
type ObjectSchema<T> = BaseSchema<T> & {
fields: { [K in keyof T]?: Schema<T[K]> };
}
// If the given T is an Enum.
type EnumSchema<T> = BaseSchema<T> & {
enums: T[];
}
The usage sample:
// Create a User type.
type User = {
name: string;
status: Enum<'verified' | 'created'>;
}
// Create a User schema definition.
const userSchema: Schema<User> = {
type: 'object', // Correct.
fields: {
name: {
type: 'string', // Correct.
default: 'John', // Correct.
},
status: {
type: 'enum', // ERROR!: type "enum" is not assignable to type "string".
enums: ['verified', 'created'], // ERROR!: Type "verified" is not assignable to type "created".
default: 'created' // Correct.
}
}
}
// Create a User object.
const user: User = {
name: 'Smith',
status: 'test', // Expected error: type "test" is not assignable to type "verified" | "created".
}
As you can see, the type: 'enum'
is raising an error because the Enum
output is a string, and the enums: []
also raising an error because the Enum
output a single type.
So I'm stuck here, tried several methods but still no luck. Can you help me with this? Thank you so much!