0

Here i'm facing row[header.key] is showing the Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'DataType' issue i don't want to use type:any instead of any what can pass here.

Please help me thanks in advance

export interface HeaderType {
 label: string; 
 key: string
}

export interface DataType {
 isImported: string;
 type: string;
 entityId: string | undefined;
 actor?: string | undefined;
 additionalInformation?: { [key: string]: string } | undefined;
}

const convertToCsv = (headers: Array<HeaderType>, data: Array<DataType>) => {
  const csvRows = [];
  const headerValues = headers.map(header => header.label);
   csvRows.push(headerValues.join(','));
   data?.forEach(row => {
  const rowValues = headers.map(header => {
  let escaped;
  if (typeof row[header.key] === 'object') {
    const str = JSON.stringify(row[header.key], null, 1);
    escaped = str?.replace(/"/g, '');
  } else if (row[header.key] && /"/g.test(row[header.key])) {
    escaped = row[header.key].replace(/"/g, '');
  } else {
    escaped = row[header.key] ? row[header.key].replace(/"/g, '\\"') : '';
  }
  return `"${escaped}"`;
 });
 csvRows.push(rowValues.join(','));
});
return csvRows.join('\n');
};

 const generateCSV = (
   header: Array<HeaderType>,
   data: Array<DataType> ,
 ) => convertToCsv(header, data);

 export default generateCSV;
sonam
  • 105
  • 8
  • Does this answer your question? [Element implicitly has an 'any' type because expression of type 'string' can't be used to index](https://stackoverflow.com/questions/57086672/element-implicitly-has-an-any-type-because-expression-of-type-string-cant-b) – Jimmy Jan 30 '23 at 08:01
  • How can i passed the `keyof` thing in my code – sonam Jan 30 '23 at 08:12
  • `keyof` is not a thing you pass. You're trying to access a field of `DataType` using an arbitrary string, but `DataType` does not have all possible string properties, only the 5 you specified. You either need to add an index signature to `DataType` or do something to prove that the value of `header.key` is one of the 5 properties of `DataType`. – Jimmy Jan 30 '23 at 08:20
  • How can i add the `header.key` is the value of the 5 properties of DataType, can you gave me sample – sonam Jan 30 '23 at 08:28

3 Answers3

0

I am not sure if I understood your question correctly.

In order to do this you first have to make sure that key in the Headertype is a key of Datatype:

export interface HeaderType {
  label: string;
  key: keyof DataType; // <-- key should be a key of DataType
}

Then in the function use a local variable to let Typescript infer the type. (Currently string | {[p: string]: string} )

const convertToCsv = (headers: Array<HeaderType>, data: Array<DataType>) => {
  const csvRows = [];
  const headerValues = headers.map((header) => header.label);
  csvRows.push(headerValues.join(','));
  data?.forEach((row) => {
    const rowValues = headers.map((header) => {
      let escaped;
      const value = row[header.key]; // <- local constant so Typescript can infer the typing 
  ....

Then your code should compile just fine.

berse2212
  • 464
  • 5
0

PLAYGROUND

Code

export interface DataType {
 isImported: string;
 additionalInformation?: { [key: string]: string } | undefined;
}

const a: DataType = {
    isImported:"true",
    "additionalInformation": {a:"string"}
}

const b:string = "isImported"

// a[b] would error

if(b in a){
    // you can use hasOwnProperty if preferred.
    console.log(a[b as keyof DataType])
}

Explanation:

  • the error is that you are accessing dataType[x] where x is not guaranteed to belong to dataType
  • So I used in. To prove that x belongs to the dataType.
    • You can also use other operators, since in looks also in the prototype. For example, .hasOwnProperty.
  • If your header.key is guaranteed to belong to DataType, see @berse2212 solution.
Minsky
  • 2,277
  • 10
  • 19
-1

The row[header.key] expression's absence of type information is the cause of this problem. You must convert the row[header.key] type to string in order to address the issue. This may be achieved by following the expression with the type assertion operator as string, as in:

Here's the updated code with the fix:

const rowValue = row[header.key] as string;
  • 1
    Using type assertions defeats the purpose of TypeScript, which is to catch mistakes like this. This also doesn't resolve OP's error, because the error is from the object access itself, not because of the type of the resulting value. – Jimmy Jan 30 '23 at 09:29