He creado un componente de reacción genérico de la siguiente manera:
export interface GenericTableProps<T extends Record<string, unknown>> { columns: Column<T>[]; data: T[]; } const GenericTable = <T extends Record<string, unknown>>({ columns, data, }: GenericTableProps<T>): ReactElement => { ... }Así es como uso este componente:
const data: StudentsDto[] = useMemo(() => tableData ?? [], [tableData]); const columns: Column<StudentsDto>[] = useMemo(() => tableColumns, []); <GenericTable columns={columns} data={data} />Esto me da un error mecanografiado:
Type 'StudentsDto[]' is not assignable to type 'Record<string, unknown>[]'. Type 'StudentsDto' is not assignable to type 'Record<string, unknown>'. Index signature for type 'string' is missing in type 'StudentsDto' StudentsDto tiene el siguiente aspecto:
export interface StudentsDto { index?: number; name?: string; lastName?: string; dob?: string; ... } Debo mencionar que no puedo actualizar la interfaz StudentsDto , ya que se genera usando openApi.
Como puedo resolver esto ?
Puede eliminar las extends Record<string, unknown> o agregar una firma de índice a sus const data: StudentsDto & {[key: string]: unknown}[] = ...
La respuesta más directa es usar Record<string, any> en lugar de Record<string, unknown> . El caso de uso general de tipo unknown es cuando tenemos que reducir los tipos. Por ejemplo,
function fn(g: unknown) { if(typeof g === 'string'){ g; //here g would be string console.log(g.toLowerCase()); // typescript will not yell us about wrong types } if(typeof g === 'function'){ g; // function type console.log(g.name); // can access name property of function } } Con Record<string, any> type significa que estamos seguros de que coincidirá con any object y not any type , ya sea que tengan una firma de índice inferida o no.
La razón obvia por la que funciona con Record<string, any> y no Record<string, unknow> se proporciona aquí en este número .
Este error se debe a la inferencia de tipo de mecanografiado ( aquí está el documento oficial y una respuesta relacionada que puede ayudar a entenderlo)
Como @subrato-pattanaik vio bien, se debe usar unknown cuando reduzca los tipos después. Y puede usar any para aceptar cualquier tipo.
Para su caso particular, si necesita hacer que la interfaz GenericTableProps acepte diferentes tipos...
y algunos de ellos que no conoces en este momento: usaría un tipo de object , ya que es más legible que Record<string, any> (diferencias aquí )
export interface GenericTableProps<T extends object> { //... y los conoce a todos: crearía una nueva interfaz que extienda todos los tipos que GenericTableProps puede aceptar y usaría ese tipo en particular. Este enfoque es el preferido porque tendrá tipos más estrechos y eso puede ayudarlo a evitar errores tipográficos.
interface GenericTableDataType extends StudentsDto, ProfessorsDto {} export interface GenericTableProps<T extends GenericTableDataType> { //...