[typescript] React.ReactElement type is not compatible with Preact and prevents interoperability with React
See original GitHub issueThere is a type mismatch between React.ReactElement
and preact.VNode
that prevents usage of typescript/react code with typescript/preact.
While the code below compiles and works without an issue, Typescript typechecking fails.
Reproduction
import type React from 'react'
import { FunctionalComponent, h } from 'preact'
const ReactFCInterlop: React.FC = () => {
return <span>hello</span>
}
const Home: FunctionalComponent = () => {
return (
<div>
<ReactFCInterlop /> // this fails to typecheck
</div>
)
}
export default Home
This results in the following typescript error:
$ tsc
src/routes/home/index.tsx:11:14 - error TS2786: 'ReactFCInterlop' cannot be used as a JSX component.
Its return type 'ReactElement<any, any> | null' is not a valid JSX element.
Type 'ReactElement<any, any>' is missing the following properties from type 'Element': nodeName, attributes, children
11 <ReactFCInterlop />
~~~~~~~~~~~~~~~
Typescript config:
$ tsc --showConfig
{
"compilerOptions": {
"skipLibCheck": true,
"target": "es5",
"module": "esnext",
"allowJs": true,
"jsx": "preserve",
"jsxFactory": "h",
"noEmit": true,
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true
},
"files": [
"./src/components/app.tsx",
"./src/components/header/index.tsx",
"./src/routes/home/index.tsx",
"./src/routes/notfound/index.tsx",
"./src/routes/profile/index.tsx",
"./src/tests/header.test.tsx",
"./src/types.d.ts",
"./src/components/header/style.css.d.ts",
"./src/routes/home/style.css.d.ts",
"./src/routes/notfound/style.css.d.ts",
"./src/routes/profile/style.css.d.ts",
"./src/tests/declarations.d.ts"
],
"include": [
"src/**/*.tsx",
"src/**/*.ts"
]
}
Deps:
$ npm ls --depth 0 | grep preact
├── enzyme-adapter-preact-pure@2.2.3
├── jest-preset-preact@4.0.2
├── preact@10.4.8
├── preact-cli@3.0.1
├── preact-jsx-chai@3.0.0
├── preact-markup@2.0.0
├── preact-render-to-string@5.1.10
├── preact-router@3.2.1
Tested with Typescript: 4.0.2
/ 3.9.7
Expected Behavior
Preact should be able to interlope with components that use typescript and @types/react
. There a lot of components like that.
Workaround
This is a very dumb workaround, but it works:
// src/types.d.ts
import React from 'react'
declare global {
namespace React {
interface ReactElement {
nodeName: any
attributes: any
children: any
}
}
}
Issue Analytics
- State:
- Created 3 years ago
- Reactions:15
- Comments:17 (7 by maintainers)
Top Results From Across the Web
TypeScript | Preact: Fast 3kb React alternative with the same ...
There are different ways to type components in Preact. Class components have generic type variables to ensure type safety. TypeScript sees a function...
Read more >Fixing JSX types between Preact and React Libraries
How to fix JSX TypeScript errors due to incompatible types between Preact and imported React component libraries, especially for JSX.
Read more >NPM package cannot be used as a JSX Component
The types returned by 'render()' are incompatible between these types. Type 'React.ReactNode' is not assignable to type 'import("/home/user/app/ ...
Read more >Try React 17 now— learn what's new in v17 and what does it ...
React is maturing and it is now on version 16.x, version 17 is expected to come out ... React itself as well as...
Read more >warning: [antd: form.item] `name` is only used for validate react ...
Item] name is only used for validate React element. ... Because we have adjusted the minimum requirements for compatibility, ... Stop IE9/10 support....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
May I suggest that this issue is marked as a documentation issue by adding @Svampen fix to the Typescript Configuration section in the docs.
@Svampen suggests above adding the following to
tsconfig.json
:The paths are relative to the
baseUrl
so if you change that, which you might, you must change the paths accordingly, for example, if you have"baseUrl":"./src"
then your paths would start with../node_modules
(double-dot).You have no control over what and how other imported packages and their dependencies reference and cause
@types/react
to be installed. Any potential developer who adds@types/react
as a dependency instead of apeerDependency
in theirpackage.json
will cause the same issue. It might be Enzyme or, as it is my case, a dependency of a dependency ofreact-bootstrap
but it might be anything else in the future, you have no control over that.Whichever way it gets loaded, once it is, you are in trouble. By equating the paths to
react
andreact-dom
topreact/compat
throughtsconfig.json
, it doesn’t matter which dependent package imports those definitions, it won’t even look at@types/react
even if it does get installed intonode_modules
, it will simply be ignored.This has been added to the dos in https://github.com/preactjs/preact-www/pull/850 thank you @satyam