skip to Main Content

Using React with Typescript I am trying to do the simple thing, that is iterate through a collection of object and based on each of those – create an instance of custom component.

Given that I’m using map function, i do get the index so I’m using this as key.

Problem: getting a red squigly when setting key with message:

Type ‘{ imageSource: string; target: string; title: string; hasGap:
boolean | undefined; key: number; }’ is not assignable to type
‘IntrinsicAttributes & { hasGap?: boolean | undefined; imageSource:
string; title: string; target: string; disabled?: boolean | undefined;
} & { children?: ReactNode; }’. Property ‘key’ does not exist on
type ‘IntrinsicAttributes & { hasGap?: boolean | undefined;
imageSource: string; title: string; target: string; disabled?: boolean
| undefined; } & { children?: ReactNode; }’.ts(2322)

Now in my understanding, key property should exist by default on every React component so I do not understand where’s that error coming from…

Example of a simple component, not even using map:

const MissingKeyComponent = () => {
  return(
    <div>Key cannot be passed when creating this component</div>
  )
}

<MissingKeyComponent key={100}></MissingKeyComponent>

enter image description here

In real life example code runs well, browser does not show any errors, as well as Vite output…

If i remove the key, browser shows standard error about missing key when creating list of components.

In addition – I do have ESLint installed, as well as prettier.

My tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "noFallthroughCasesInSwitch": true,
    "jsx": "react-jsx",
    "types": ["vite/client", "node"],

    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "react": ["node_modules/@types/react"]
    }
  },
  "include": ["src", "types"],

  "references": [
    {
      "path": "./tsconfig.node.json"
    }
  ]
}

My .eslintrc.cjs

module.exports = {
  root: true,
  settings: {
    react: {
      version: 'detect',
    },
  },
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'plugin:@typescript-eslint/recommended-type-checked',
    'plugin:@typescript-eslint/stylistic-type-checked',
    'plugin:react-hooks/recommended',
    'prettier',
  ],
  ignorePatterns: ['dist', '.eslintrc.cjs'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: ['./tsconfig.json', './tsconfig.node.json'],
    tsconfigRootDir: __dirname,
  },
  plugins: ['react-refresh'],
  rules: {
    'react-refresh/only-export-components': [
      'warn',
      { allowConstantExport: true },
    ],
    'react/no-unknown-property': ['error', { ignore: ['css', 'tw'] }],
    '@typescript-eslint/no-unused-vars': ['warn'],
    'no-unused-vars': 'off',
  },
};

2

Answers


  1. Chosen as BEST ANSWER

    Ok, so I found the issue:

    I am using Tailwind with Twin Macro in my project. This forces type extension to be created:

    file twin.d.ts

    import 'twin.macro';
    import styledImport, { CSSProp, css as cssImport } from 'styled-components';
    
    declare module 'twin.macro' {
      // The styled and css imports
      const styled: typeof styledImport;
      const css: typeof cssImport;
    }
    
    declare module 'react' {
      // The css prop
      interface HTMLAttributes<T> extends DOMAttributes<T> {
        css?: CSSProp;
        tw?: string;
      }
    
      // The inline svg css prop
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      interface SVGProps<T> extends SVGProps<SVGSVGElement> {
        css?: CSSProp;
        tw?: string;
      }
    }
    
    //The 'as' prop on styled components
    declare global {
      namespace JSX {
        interface IntrinsicAttributes<T> extends DOMAttributes<T> {
          as?: string | Element;
        }
      }
    }
    

    The issue was that

    declare global {
      namespace JSX {
        interface IntrinsicAttributes<T> extends DOMAttributes<T> {
          as?: string | Element;
        }
      }
    }
    

    Should be written like that:

    declare module 'react/jsx-runtime' {
      interface IntrinsicAttributes<T> extends React.DOMAttributes<T> {
        as?: string | Element;
      }
    }
    

    Everything is working fine!


  2. Have you tried simply closing your editor and reopening it? Sometimes VS code gets a little wacky.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search