Search code examples
reactjstypescriptreact-nativestyled-components

Styled Components & Typescript type error


I've set up styled-components successfully in react-native, but I'm now using react-native-web and can't get styled-components to work on the web in this very simple example:

import * as React from 'react';
import styled from 'styled-components';

export default class View extends React.PureComponent {
  public render() {
    return (
      <Container>
        <h1>Hey</h1>
      </Container>
    );
  }
}

const Container = styled.div;

I'm getting this error:

Type error: JSX element type 'StyledComponentClass<DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, a...' is not a constructor function for JSX elements.
Property 'render' is missing in type 'StyledComponentClass<DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, a...'.  TS2605
> 11 |       <Container>

This is my tsconfig.json:

"target": "es6",
"jsx": "preserve",
"module": "esnext",
"sourceMap": true,
"outDir": "dist",
"types": [
  "react",
  "react-native",
  "jest"
],
"skipLibCheck": true,
"lib": [
  "es2015.promise",
  "esnext",
  "dom"
],
"alwaysStrict": false,
"downlevelIteration": true,
"strict": false,
"strictNullChecks": false,
"allowJs": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true

And my package.json:

...
"devDependencies": {
  ...
  "@types/react": "^16.7.20",
  "@types/react-dom": "^16.7.20",
  "@types/react-native": "^0.52.25",
  "typescript": "^2.9.2"
},
"dependencies": {
  ...
  "react": "16.3.1",
  "react-dom": "^16.7.0",
  "styled-components": "^3.4.5",
}

I've tried to rm -rf node_modules; rm package-lock.json; npm install to no avail.

Probably missing something simple here, but anyone have any ideas? Not sure what other information I can provide.


Solution

  • You'll want to use the React Native component instead of standard HTML tags. Instead of styled.div, you'll use styled.View. Also you have to use react native's Text component in replace of standard HTML tags that would hold textual data such as <H1>.

    So, this is what your code should translate to

    import * as React from 'react'
    import { Text } from 'react-native'
    import styled from 'styled-components/native'
    
    export default class View extends React.PureComponent {
        render() {
            return(
                <Container>
                    <Text>Hey</Text>
                </Container>
            )
        }
    }
    
    const Container = styled.View