3

I want to build a component that takes an Icon parameter and passes all other parameters to a styled-component Input (based on TextInput). In Javascript, it's quite straightforward:

import React from 'react';
import { TextInput } from 'react-native';
import styled from 'styled-components/native';

const Input = styled.TextInput`
  color: #268596;
`;

export default ({ Icon, ...props }) => (
  <InputArea>
    <Icon fill="#268596" />
    <Input {...props} />
  </InputArea>
);

However, I want to use Typescript (in which I'm quite a beginner). I tried the following.

import React from 'react';
import { TextInputProps, TextInput } from 'react-native';
import styled from 'styled-components/native';

const Input = styled.TextInput`
  color: #268596;
`;

type InputAreaProps = {
  Icon: React.FC<React.SVGAttributes<SVGElement>>;
} & TextInputProps;

export default ({ Icon, ...props }: InputAreaProps) => (
  <InputArea>
    <Icon fill="#268596" />
    <Input {...props} />
  </InputArea>
);

I get all intellisense and autocompletion for TextInput parameters, but TypeScript isn't happy. It keeps complaining here:

    <Input {...props} />
     ^^^^^

And saying:

No overload matches this call.
  Overload 1 of 2, '(props: Omit<Omit<TextInputProps & RefAttributes<TextInput>, never> & Partial<Pick<TextInputProps & RefAttributes<TextInput>, never>>, "theme"> & { ...; } & { ...; } & { ...; }): ReactElement<...>', gave the following error.
Type '{ allowFontScaling?: boolean | undefined; autoCapitalize?: "none" | "sentences" | "words" | "characters" | undefined; autoCorrect?: boolean | undefined; autoFocus?: boolean | undefined; ... 103 more ...; showSoftInputOnFocus?: boolean | undefined; }' is not assignable to type 'Omit<Omit<TextInputProps & RefAttributes<TextInput>, never> & Partial<Pick<TextInputProps & RefAttributes<TextInput>, never>>, "theme">'.
      Types of property 'style' are incompatible.
        Type 'import("/Projects/node_modules/@types/react-native/index").StyleProp<import("/Projects/node_modules/@types/react-native/index").TextStyle>' is not assignable to type 'import("/Projects/node_modules/@types/styled-components-react-native/node_modules/@types/react-native/index").StyleProp<import("/Projects/node_modules/@types/styled-components-react-native/node_modules/@types/react-native/index").TextStyle>'.
          Type 'TextStyle' is not assignable to type 'StyleProp<TextStyle>'.
            Type 'import("/Projects/node_modules/@types/react-native/index").TextStyle' is not assignable to type 'import("/Projects/node_modules/@types/styled-components-react-native/node_modules/@types/react-native/index").TextStyle'.
              Types of property 'color' are incompatible.
                Type 'import("/Projects/node_modules/@types/react-native/index").ColorValue | undefined' is not assignable to type 'import("/Projects/node_modules/@types/styled-components-react-native/node_modules/@types/react-native/index").ColorValue | undefined'.
                  Type 'unique symbol' is not assignable to type 'ColorValue | undefined'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<typeof TextInput, DefaultTheme, {}, never, typeof TextInput>): ReactElement<StyledComponentPropsWithAs<typeof TextInput, DefaultTheme, {}, never, typeof TextInput>, string | JSXElementConstructor<...>>', gave the following error.
    Type '{ allowFontScaling?: boolean | undefined; autoCapitalize?: "none" | "sentences" | "words" | "characters" | undefined; autoCorrect?: boolean | undefined; autoFocus?: boolean | undefined; ... 103 more ...; showSoftInputOnFocus?: boolean | undefined; }' is not assignable to type 'Omit<Omit<TextInputProps & RefAttributes<TextInput>, never> & Partial<Pick<TextInputProps & RefAttributes<TextInput>, never>>, "theme">'.
      Types of property 'style' are incompatible.
        Type 'import("/Projects/node_modules/@types/react-native/index").StyleProp<import("/Projects/node_modules/@types/react-native/index").TextStyle>' is not assignable to type 'import("/Projects/node_modules/@types/styled-components-react-native/node_modules/@types/react-native/index").StyleProp<import("/Projects/node_modules/@types/styled-components-react-native/node_modules/@types/react-native/index").TextStyle>'

What can I do to make TypeScript happy? And where I can look to try spot these kind of things myself?

1 Answer 1

7

Can you try to wrap the TextInput in styled component instead of using dot notation. Maybe there is conflict with another TextInput somewhere.

import { TextInputProps, TextInput } from "react-native";
import styled from 'styled-components';

const Input = styled(TextInput)` // using styled()
  color: #268596;
`;

type InputAreaProps = {
    Icon: React.FC<React.SVGAttributes<SVGElement>>;
} & TextInputProps;

export default ({ Icon, ...props }: InputAreaProps) => (
  <InputArea>
    <Icon fill="#268596" />
    <Input {...props} />
  </InputArea>
);
Sign up to request clarification or add additional context in comments.

4 Comments

It worked, thanks! But I didn't understand why it works.
I dive deep to the code and I figure out you should be using styled-components-react-native, right? styled-components-react-native contains its own react-native component definition which has conflict with the react-native one. You are using TextInputProps from 'react-native', but the Input -> TextInputProps is using styled-components-react-native one. Therefore, type mismatched
using styled(TextInput) will use back react-native type definition and TextInputProps is also from react-native side. So, problem solved
I check that they are fixing some issue. maybe there is one related to your case github.com/DefinitelyTyped/DefinitelyTyped/pull/49914

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.