Home > Net >  Typescript Cannot assign type '{ [key: string]: string; }[]' to type 'T[]'
Typescript Cannot assign type '{ [key: string]: string; }[]' to type 'T[]'

Time:03-09

I have an independent helper function which allows to filter an array of objects by string key:

function filterRows(
  rows: Array<{ [key: string]: string }>,
  searchKey: string
) {
  return rows.filter((obj) =>
    Object.keys(obj).some((key) => obj[key].toString().includes(searchKey))
  );
}

In a component, I have a variable TableRowsCells of type Array<T> (component infer type)

So, this variable can have value; examples:

const TableRowsCells = [
  {
    firstname: 'John',
    lastname: 'Adams'
  },
  {
    firstname: 'Paul',
    lastname: 'Walker'
  },
];

or

const TableRowsCells = [
  {
    company: 'Vody aho',
    nb_employees: 1590,
    country: 'Hong Kong'
  },
  {
    company: 'Royal spirit',
    nb_employees: 15,
    country: 'USA'
  },
];

Now i want to filter this variable using above helper function:

type EnhancedTableProps<T> = {
  TableRowsCells: Array<T>;
  searchKey?: string;
};

function EnhancedTable<T>({ TableRowsCells, searchKey }: EnhancedTableProps<T>) {
  /** Code stuff...**/

  let outputRowsItems = TableRowsCells;
  if (typeof searchKey === 'string' && searchKey.length > 2) {
    outputRowsItems = filterRows(TableRowsCells, searchKey);
  }

  /** Code stuff...**/
}

Like this, I have 2 errors for typescripts:

Error 1 (outputRowsItems = filterRows(TableRowsCells, searchKey); in outputRowsItems):

Cannot assign type '{ [key: string]: string; }[]' to type 'T[]'.
  Cannot assign type '{ [key: string]: string; }' to type 'T'.
    'T' could have been instantiated with an arbitrary type which may not be related to '{ [key: string]: string; }'.ts(2322)

Error 2 (outputRowsItems = filterRows(TableRowsCells, searchKey); in TableRowsCells ):

(parameter) TableRowsCells: T[]
Argument of type 'T[]' is not assignable to parameter of type '{ [key: string]: string; }[]'.
  Cannot assign type 'T' to type '{ [key: string]: string; }'.ts(2345)

At the end, I want outputRowsItems to have the same type as TableRowsCells i.e. Array<T>

Could you please help me to solve these errors?

Playground link

thx

CodePudding user response:

To preserve the type of the input, you need to use a generic type parameter for filterRows

function filterRows<T extends Record<keyof T, string>>(
  rows: Array<T>,
  searchKey: string
) {
  return rows.filter((obj) =>
    Object.keys(obj).some((key) => obj[key as keyof T].toString().includes(searchKey))
  );
}

Playground Link

CodePudding user response:

You can do it something like -

type TableRowsCells = Array<Record<string, string | number>>;
type SearchKey = string;

type EnhancedTableProps = {
  TableRowsCells: TableRowsCells,
  searchKey?: SearchKey;
};

function filterRows(
  rows: TableRowsCells,
  searchKey: SearchKey
) {
  return rows.filter((obj) =>
    Object.keys(obj).some((key) => obj[key].toString().includes(searchKey))
  );
}

function EnhancedTable({ TableRowsCells, searchKey }: EnhancedTableProps) {
  /** Code stuff...**/

  let outputRowsItems = TableRowsCells;
  if (typeof searchKey === 'string' && searchKey.length > 2) {
    outputRowsItems = filterRows(TableRowsCells, searchKey);
  }

  /** Code stuff...**/
}

Playground Link

  • Related