Definitelytyped: [styled-components] v4 doesn't support React Native

Created on 16 Oct 2018  路  23Comments  路  Source: DefinitelyTyped/DefinitelyTyped

  • [x] I tried using the @types/[email protected] package and had problems.
  • [x] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [x] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @Igorbek @Igmat @Lavoaster

Latest version of @types/styled-components doesn't support React Native.

If you're trying to:

import styled from "styled-components/native";

TypeScript throws an error:
Error: TS7016: Could not find a declaration file for module 'styled-components/native'. '[project_path]/node_modules/styled-components/native/dist/styled-components.native.cjs.js' implicitly has an 'any' type.

Also when you're trying to:

import styled from "styled-components";

and declare native component like this:

const Test = styled.View`...`

it also throws an error:
Error: TS2551: Property 'View' does not exist on type 'ThemedBaseStyledInterface<any>'. Did you mean 'view'?

Most helpful comment

Fixed now that @types/[email protected] is published! This issue should be closable as the typings provide basic support for styled-components/native now. Please let me know if anyone runs into issues!

All 23 comments

Please also have in mind to support possibility to pass custom Theme interface into ThemedStyledComponentsModule connected with Native just like it's shown in documentation (it isn't updated to v4):

// theme.ts
export default interface ThemeInterface {
  primaryColor: string;
  primaryColorInverted: string;
}
// styled-components.ts
import * as styledComponents from "styled-components";
import { ThemedStyledComponentsModule } from "styled-components";

import ThemeInterface from "./theme";

const {
  default: styled,
  css,
  injectGlobal,
  keyframes,
  ThemeProvider
} = styledComponents as ThemedStyledComponentsModule<ThemeInterface>;

export { css, injectGlobal, keyframes, ThemeProvider };
export default styled;

I think @types/styled-components never supported react-native, the reason why it was working previously is that it's referencing the type definition inside styled-components and not @types/styled-components and now they have removed it completely from styled-components.

I think current workarounds are:

  1. Keep using styled-components@3
  2. Instead of styled.View, do styled(View) instead.

A small drawback with the 2nd approach is that you need to import View, but you get to use the latest version.

Also, there was PR https://github.com/styled-components/styled-components/pull/1844

But I dont think it was carried over to this repo.

Any updates to this? Any plans in having a type definitions for react-native?

Any updates to this?

I think current workarounds are:

  1. Keep using styled-components@3
  2. Instead of styled.View, do styled(View) instead.

A small drawback with the 2nd approach is that you need to import View, but you get to use the latest version.

Also, there was PR styled-components/styled-components#1844

But I dont think it was carried over to this repo.

If i try use 2nd approach, i catch exeption :

Type '{ children: Element[]; }' has no properties in common with
type 'IntrinsicAttributes & Pick<Pick<ViewProps &
RefAttributes<View>, "style" | "hitSlop" | "onLayout" | "pointerEvents" |
"removeClippedSubviews" | "testID" | "nativeID" 
| ... 38 more ... | "ref"> & Partial<...>, "style" | ... 44 more ... 
| "ref"> & { ...; } & { ...; }'.

I have a code:

const Wrapper = styled(View)`
  background-color: #fff;
  flex: 1;
`;

class Search extends Component {
  render() {
    retrurn(
      <Wrapper>
        <Text>Search</Text>
      </Wrapper>
    );
  }
}

@egorAva that's due to new changes in React.d.ts

See my comments here https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30536#issuecomment-448489437

Maybe there could be different types package from npm for different case

eg. if you use plain react use @types/styled-components otherwise use @types/styled-components-native

or something like @types/[email protected].

馃

I've read the various issues and tried the suggestions but I'm still lost. Is there currently any reasonable way to use styled-components with react-native in TypeScript?

Also since react-native default styling method is already pretty similar to styled-components but I still like separate components, instead of passing in style, perhaps a new simple library could be created that could be used something like this:

interface ButtonProps {
  secondary?: boolean;
}

const Button = styled<ButtonProps>(View, (props) => ({
  alignItems: "center",
  backgroundColor: props.secondary ? props.theme.bg.secondary : props.theme.bg.primary
}));

Currently without using anything extra, the best I could come up with for a custom component with some custom props is:

components/Button.tsx

import React from "react";
import {
  Text,
  TextStyle,
  TouchableNativeFeedback,
  TouchableNativeFeedbackProps,
  View,
  ViewStyle
} from "react-native";

import { theme } from "../constants/theme";

export interface ButtonProps {
  secondary?: boolean;
}

export const Button: React.SFC<
  ButtonProps & TouchableNativeFeedbackProps
> = props => (
  <TouchableNativeFeedback {...props}>
    <View style={viewStyle(props)}>
      <Text style={textStyle(props)}>{props.children}</Text>
    </View>
  </TouchableNativeFeedback>
);

const viewStyle = ({ secondary }: ButtonProps): ViewStyle => ({
  alignItems: "center",
  flex: 1,
  ...(secondary
    ? { borderWidth: 2, borderColor: theme.bg.primary }
    : { backgroundColor: theme.bg.primary })
});

const textStyle = ({ secondary }: ButtonProps): TextStyle => ({
  padding: 20,
  color: secondary ? theme.bg.primary : theme.text.secondary
});

Usage example:

import { Button } from "../components/Button";
...
<View>
  <Button onPress={() => Vibration.vibrate(50, false)}>
    Primary button
  </Button>
  <Button
    secondary
    onPress={() => Alert.alert("You clicked the secondary button")}
  >
    Secondary button
  </Button>
</View>

Where the theme is a simple constants file:

constants/theme.ts

export const theme = {
  text: {
    primary: "#111",
    secondary: "#FFF"
  },
  bg: {
    primary: "#2196F3"
  }
};

It's ok I guess but does anyone have a better pattern to achieve this?

@kallaspriit I'm used styled-components v3. It works with react-native and TS.
like this:

import styled from "styled-components/native";

const ViewPlaceholder = styled.View`
  flex: 1;
  align-items: center;
  padding-top: 15%;
`;

@egorAva I did the same - downgraded to v3.

So react native has been dropped?

There's nothing blocking anyone from making a PR to add a native.d.ts to https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/styled-components is there? It shouldn't be too difficult to use most of the existing infrastructure in the already written index.d.ts to accomplish this

@JKillian where is that native.d.ts?

@elyalvarado Someone has to write it! 馃槃 It's definitely a non-trivial task to understand the existing types, but it still should be doable to add typings for styled-components/native

I've made a PR to add typings for styled-components/native, please feel free to review!

Fixed now that @types/[email protected] is published! This issue should be closable as the typings provide basic support for styled-components/native now. Please let me know if anyone runs into issues!

Great news! Testing now, thanks for this. Was really looking forward to using styled-components with react native

@JKillian according to the docs you should re-export the styled function with ThemedStyledComponentsModule and passing the individual theme interface to it in order to get autocomplete and error checks for your custom theme.

Unfortunately I wasn't able to find a ThemedStyledComponentsModule interface in your typings. Any chance you could add this as well?

Update:
See here

I'm having the problem again with v5.0.1...

Fixed by installing npm i -D @types/styled-components. Sorry for disturbing.

Was this page helpful?
0 / 5 - 0 ratings