Hola, estoy tratando de agregar el tipo correcto al objeto con valores anidados.
Aquí está el código en sandbox: https://codesandbox.io/s/0tftsf
interface Product { name: string, id: number productList?:ProductItem[] } interface ProductItem { color: string, size: number } type IValidation<T> = { field: keyof T nestedValidations?: IValidation< Pick< T, { [K in keyof T]-?: T[K] extends object ? K : never }[keyof T] > >[] // THIS IS IMPORTANT FOR QUESTION! validators?: (any | any | any)[] } export async function validateIt<T>(payload: T, validations: IValidation<T>[]): Promise< Partial<{ [key in keyof T]: string[] }> > { return Promise.resolve(payload); } const product: Product = { id: 1, name: 'playstation', productList: [{ color: 'red', size: 32 } ] } const test = validateIt<Product>(product, [ { field: "productList", validators: [], nestedValidations: [ { field: 'color', validators: [] } ] } ])Así que obtengo un error de tipo y, en general, estoy tratando de encontrar el tipo correcto para la propiedad nestedValidations , que debería coincidir con la interfaz Producto
Puede lograr esto con la palabra clave in combinación con keyof . Básicamente, va a "generar" todos los tipos posibles para cada clave y TypeScript encontrará uno que coincida
type IValidation<T> = T extends Array<infer R> ? IValidation<R> : T extends object ? { [K in keyof T]: { field: K nestedValidations?: IValidation<T[K]>[] validators?: (any | any | any)[] } }[keyof T] : neverTal vez no veo el panorama general, pero creo que quieres lograr esto:
interface Product { name: string, id: number } type ValueOf<T> = T[keyof T]; // not needed type IValidation<T> = { field: keyof T nestedValidations?: IValidation<T>[] // THIS IS IMPORTANT FOR QUESTION! validators?: (any | any | any)[] } export async function validateIt<T>(payload: T, validations: IValidation<T>[]): Promise< Partial<{ [key in keyof T]: string[] }> > { return Promise.resolve(payload); } const product: Product = { id: 1, name: 'playstation' } const test = validateIt<Product>(product, [ { field: "id", validators: [], nestedValidations: [ { field: "name", validators: [] } ] } ])Juega por aquí: Typescript Playground
Tenga en cuenta que tuve que simplificar su estructura de datos ya que no sé cómo se define 'IRequidValidator'.
Así que básicamente cambiamos de
nestedValidations?: IValidation<ValueOf<T>>[]a
nestedValidations?: IValidation<T>[]porque quieres extraer las claves de T y no las claves de (keys of T) Ya que eso resolvería todas las propiedades del tipo de un valor asignado a una propiedad de T.