im trying to do something like fieldsConfig for map my fields and render then by switch by type and return needed component, but i cant get value of nested property when my field name is dynamic
the problem is probably somewhere here, (solution from stackoverflow)
type PossibleFields<T>
import {
FieldPath,
FieldValues,
UseControllerProps,
UseControllerReturn
} from "react-hook-form";
type FieldPath
-> link FieldPath
type FieldValues = Record<string, any>;
type UseControllerProps
-> link UseControllerProps
type UseControllerReturn
-> link UseControllerReturn
interface HookField<
T extends FieldValues = FieldValues,
K extends FieldPath<T> = FieldPath<T>
> extends UseControllerProps<T, K> {
// tpm solution, add new key here,
// tName?: K;
render?: (props: UseControllerReturn<T, K>) => void;
}
type PossibleFields<T> = FieldPath<T> extends infer K
? K extends FieldPath<T>
? HookField<T, K>
: never
: never;
export function hookFields<T extends FieldValues = FieldValues>(
fields: Array<PossibleFields<T>>
) {
// return fields.map(() => {
// logic to render different fields by type
// will be here
// })
return fields;
}
interface Values {
test: string;
arr: Array<{
id: string;
}>;
}
const consoleString = (value: string) => console.log(value);
hookFields<Values>([
{
name: "test",
render: ({ field: { value } }) => {
consoleString(value);
}
}
]);
[].map((k, index) => {
hookFields<Values>([
{
name: `arr.0.id`,
render: ({ field: { value } }) => {
consoleString(value);
}
},
{
name: `arr.${index}.id` as const,
render: ({ field: { value } }) => {
// var value: any
// Binding element 'value' implicitly has an 'any' type.ts(7031)
consoleString(value);
}
}
]);
});
with normal field name as string
, everything is fine and im getting field value as well
but when field name is generated dynamically i cant get valid value type, is any
just interesting case, typescript understand what dynamic key is exist in array arr.${number}.id
type GetFieldKeys<T> = T extends Array<infer K>
? K extends { name: string }
? K['name']
: never
: never;
[].map((k, index) => {
const fields = [
{
name: `arr.0.id`,
render: ({ field: { value } }) => {
consoleString(value);
},
},
{
name: `arr.${index}.id` as const,
// tpm solution, add new key here,
// tName: `arr.0.id`;
render: ({ field: { value } }) => {
consoleString(value);
},
},
];
hookFields<Values>(fields);
type Keys = GetFieldKeys<typeof fields>;
});