Tengo una serie de objetos:
export const inputsArray: InputAttributes[] = [ { label: 'Name', type: 'text', name: 'name', required: true }, { label: 'User name', type: 'text', name: 'username', required: true }, ... ]y mapearlo así:
const inputs = inputsArray.map(input => { const value = (input.name === 'street' || input.name === 'city' || input.name === 'zipcode') // <= PROBLEM : NOT EFFECTIVE CONDITION! ? user?.address?.[input.name] : user?.[input.name] // <= TYPESCRIPT PROBLEM return ( <Input key={input.name} defaultValue={value} input={input} disabled={disabled} onChange={hadndleChange} /> ) })Información en el usuario:
export interface User { id: number, name: string, username: string, email: string, address: { street: string, city: string, zipcode: string, } phone: string, website: string, company: { name: string } }user?.[input.name] dice que "el tipo 'cadena' no se puede usar para indexar el tipo 'Usuarios'". Puedo evitar ese problema configurando [key: string] : any dentro de la interfaz de usuario, pero ¿hay algún patrón mejor?Interfaz de atributos de entrada si es necesario:
export interface InputAttributes { label: string, type: string, name: string, pattern?: string, required: boolean }Debe modificar la interfaz de InputAttributes de esta manera:
type DeepKeyOf<T> = { [K in keyof T]: T[K] extends Record<string, any> ? DeepKeyOf<T[K]> : K }[keyof T] export interface InputAttributes { label: string, type: string, name: DeepKeyOf<User>, pattern?: string, required: boolean } Ahora TypeScript sabe que la propiedad del name debe contener alguna clave de User .
Almacene los valores en una matriz, luego use Array.prototype.some() . Esto le permitirá admitir tantos nombres como desee.
const names = ['street', 'zipcode', 'city']; const value = names.some((name) => input.name === name) ? user?.address?.[input.name] : user?.[input.name];