'How do I index only the property names from another object, but leave values to be inferred?
I have the following example joi validation schema
const joiUser = {
firstName: joi.string().required(), // inferred type: joi.BoxStringSchema<joi.Box<string, true>>
lastName: joi.string().required() // inferred type: joi.BoxStringSchema<joi.Box<string, true>>
}
I would like to type cast it to a User interface, but keep the inferred types from joi
I tried using something like
type Foo = {
[P in keyof IUser]: any;
}
But then I get
const joiUser = {
firstName: joi.string().required(), // now inferred type changed to: any
lastName: joi.string().required() // now inferred type changed to: any
} as Foo
I don't want the types to change to any, I just want to have the same key names but let the values be inferred from the joi schema. How is this done if possible?
Solution 1:[1]
which version of Joi are you running because my version ("joi": "^17.5.0") doesn't infer the same type as yours (see comments)
btw, using this and conditionnal type is woking, but quite verbose if your schema as many types (have tested only string and number):
interface IUser {
firstName:string,
lastName:string,
age:number
}
const joiUser = {
firstName: joi.string().required(), // <-- infer joi.SchemaString
lastName: joi.string().required(), // <-- infer joi.SchemaString
age : joi.number() // <--infer NumberSchema
}
type Foo<T> = {
[P in keyof T]:T[P] extends string?joi.StringSchema:T[P] extends number? joi.NumberSchema:joi.Schema<T[P]>
}
// here joiUser2 is following the IUser interface rule and joi types are similar
const joiUser2:Foo<IUser> = {
firstName: joi.string().required(),
lastName: joi.string().required(),
age : joi.number(),
address : joi.string() // error as address is not part of IUser
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jerome |