By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not sure how to replicate this in webpackbin

Steps to reproduce

Create a theme file, as per the typescript guidance here

import * as styledComponents from 'styled-components';
import { ThemedStyledComponentsModule } from 'styled-components';
interface MyTheme {
  backgroundColor: string;
const defaultTheme: MyTheme = {
  backgroundColor: blue;
const {
  default: styled,
  css,
  injectGlobal,
  keyframes,
  ThemeProvider,
} = styledComponents as ThemedStyledComponentsModule<MyTheme>;
export default styled;
export { css, injectGlobal, keyframes, ThemeProvider, MyTheme, defaultTheme };

Create two styled components.

  • The inner component wraps an input element.
  • The outer component wraps the inner component.
  • Expose the input elements API to the outer component using the {...others} = props pattern.
  • import * as React from 'react';
    import styled, { defaultTheme } from './theme';
    // Inner Component
    interface IInnerComponentProps extends React.HTMLProps<HTMLInputElement> {
      foo?: string;
    const InnerComponent: React.StatelessComponent<IInnerComponentProps> = props => {
      const {foo, ...others} = props;
      return <input type="text" {...others}/>;
    const InnerStyled = styled(InnerComponent)`
      background: red;
    InnerStyled.defaultProps = defaultTheme;
    // Outer component
    interface IMyComponentProps extends React.HTMLProps<HTMLElement> {
      bar?: string;
    const MyComponent: React.StatelessComponent<IMyComponentProps> = props => {
      const {bar, ...others} = props;
      return <div><InnerStyled type="text" {...others}/></div>;
    const MyComponentStyled = styled(MyComponent)`
      color: green;
    MyComponentStyled.defaultProps = {
      theme: defaultTheme,
    

    Expected Behavior

    the line return <div><InnerStyled type="text" {...others}/></div>; should not generate a typescript error.

    Actual Behavior

    The following typescript error is generated

    Type '{ value: string; ghostValue?: string; theme?: any; defaultChecked?: boolean; defaultValue?: strin...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps<IGhostedTextInput...'.
      Type '{ value: string; ghostValue?: string; theme?: any; defaultChecked?: boolean; defaultValue?: strin...' is not assignable to type 'IntrinsicClassAttributes<Component<ThemedOuterStyledProps<IGhostedTextInputProps, IGhostedTextInp...'.
        Types of property 'ref' are incompatible.
          Type 'Ref<HTMLInputElement>' is not assignable to type 'Ref<Component<ThemedOuterStyledProps<IGhostedTextInputProps, IGhostedTextInputTheme>, ComponentSt...'.
            Type '(instance: HTMLInputElement) => any' is not assignable to type 'Ref<Component<ThemedOuterStyledProps<IGhostedTextInputProps, IGhostedTextInputTheme>, ComponentSt...'.
              Type '(instance: HTMLInputElement) => any' is not assignable to type '(instance: Component<ThemedOuterStyledProps<IGhostedTextInputProps, IGhostedTextInputTheme>, Comp...'.
                Types of parameters 'instance' and 'instance' are incompatible.
                  Type 'Component<ThemedOuterStyledProps<IGhostedTextInputProps, IGhostedTextInputTheme>, ComponentState>' is not assignable to type 'HTMLInputElement'.
                    Property 'accept' is missing in type 'Component<ThemedOuterStyledProps<IGhostedTextInputProps, IGhostedTextInputTheme>, ComponentState>'. 
    Typescript error with nested styled components
    Typescript error with nested styled, themed components
          May 24, 2017
              

    It's not a bug :) you're using the default HTMLProps and trying to pass a ref, but unfortunately the ref is now pointing to an instance of the styled component and not the underlying element ref.

    You'll either want to add a new type for ref, or more likely use innerRef instead

    cc @styled-components/typers

    vvkee, tetsuo5555, optimatex, santhoshsoundar, cristianfraser, purpledrgn, eranimo, TheGabornator, hegelstad, integration-twill, and 16 more reacted with thumbs down emoji gargantuan, rohmanhm, kevinSuttle, Jenscaasen, 8enSmith, Lillebo, mcauto, AntonyF-Andreani, sourabh-kejriwal, mattsikkema, and 3 more reacted with confused emoji All reactions

    Even more simple example generates compile-time error in TypeScript:

    const LogoBlock = styled.div`
      background-color: lime;`;
    const HeaderBlock = styled.div`
      border: 1px solid #333;
      > ${LogoBlock} {
        background: red;
    

    It gave me following error:

    error TS2345: Argument of type 'ComponentClass<ThemedOuterStyledProps<HTMLProps<HTMLDivElement>, any>>' is not assignable to parameter of type 'Interpolation<ThemedStyledProps<HTMLProps<HTMLDivElement>, any>>'.
      Type 'ComponentClass<ThemedOuterStyledProps<HTMLProps<HTMLDivElement>, any>>' is not assignable to type 'ReadonlyArray<string | number | InterpolationFunction<ThemedStyledProps<HTMLProps<HTMLDivElement>...'.
        Property 'find' is missing in type 'ComponentClass<ThemedOuterStyledProps<HTMLProps<HTMLDivElement>, any>>'.
    

    Any ideas how to handle this?

    @sergeyzwezdin the issue you've found has been fixed in v2.0.1
    @gargantuan's issue is still unfixed, maybe @Igorbek can have a look at it.

    @cesalberca please let us know if you have other issues, I haven't had too much time to play with v2 and typings :)

    Yep, there's still no fixed.

    But, I have fixed my issue by creating new React.Component

    const ButtonDefault = styled(Button)`
      background-color: ${ (props) => props.intent ? props.intent : Color.blue } !important;
    export default class extends React.Component<React.HTMLAttributes<{}> & typeof ButtonDefault.propTypes, {}> {
      public render () {
        return <ButtonDefault {...this.props}/>
              

    @gargantuan this should work:

    function toInnerRef<T>(ref: undefined | React.Ref<T>): undefined | ((instance: T | null) => void) {
        if (!ref) {
            return undefined;
        if (typeof ref === 'string') {
            throw new Error('name refs are not supported.');
        return ref;
    const MyComponent: React.StatelessComponent<IMyComponentProps> = props => {
        const { bar, ref, ...others } = props;
        const innerRef = toInnerRef(ref);
        return <div><InnerStyled type="text" {...others} innerRef={innerRef} /></div>;
    

    Note, that ref from HTMLProps and ref from StyledComponent are not covariantly compatible.
    styled-components use innerRef to reach out the ref of its inner component.

    mulholo, rsurjano, LordSeb, ABlagodyr, and declantyson reacted with thumbs down emoji kevinSuttle, lnmunhoz, ptcampbell, xrrrx1, GuillaumeMalartre, eranimo, zeddz92, straxico, RichMatthews, jefferson-gaivota, and 9 more reacted with confused emoji All reactions

    Getting a similar issue when using polished 1.8.0 and styled-component 2.2.1:

    import { ellipsis } from 'polished'; 
    const Heading = styled.div`
      ${ellipsis};
    

    Results in:

    error TS2345: Argument of type '(width?: string | number | undefined) => Object' is not assignable to parameter of type 'Interpolation<ThemedStyledProps<(ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>...'.
      Type '(width?: string | number | undefined) => Object' is not assignable to type 'ReadonlyArray<string | number | StyledComponentClass<any, any, any> | InterpolationFunction<Theme...'.
        Property 'concat' is missing in type '(width?: string | number | undefined) => Object'.
    

    ellipsis's definition returns Object, which may be incompatible with styled-components, css in JS, or tagged template literals in general. Creating my own method that returns any works, but I'm not sure what the correct type should be.

    Wrapping ellipsis like so:

    export const EllipsisWrapper = (width: string | number): any => ellipsis(width);
    

    Causes other errors such as:

    error TS2322: Type '{ children: string; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps<(FlexChildProps ...'.
      Type '{ children: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps<(FlexChildProps &...'.
        Type '{ children: string; }' is not assignable to type 'Readonly<FlexChildProps & TextAlignInterface & HTMLProps<HTMLElement> & { theme?: any; innerRef?:...'.
          Property 'toFixed' is missing in type '{ children: string; }'.
              

    If ellipsis defined as (width?: string | number | undefined) => Object then it indeed incorrect argument. An interpolation function accepts an object that consists of props and theme. It can accept neither width nor number.

    The fix should be something like this:

    const Heading = styled.div`
      ${(props: { width: number; }) => ellipsis(props.width)};
    <Header width={12} />; // usage
  • The interpolation now is a proper function taking props
  • The type of extra prop (width) was explicitly provided
  • @Igorbek thanks for the reply. I was indeed missing that extraction step for width, but I think the issue is with the Object return type, not arguments.

    The Heading styled-component you posted returns this error:

    error TS2345: Argument of type '(props: { width: number; }) => Object' is not assignable to parameter of type 'Interpolation<ThemedStyledProps<HeadingProps, ThemeInterface>>'.
      Type '(props: { width: number; }) => Object' is not assignable to type 'ReadonlyArray<string | number | StyledComponentClass<any, any, any> | InterpolationFunction<Theme...'.
        Property 'find' is missing in type '(props: { width: number; }) => Object'.
    

    Writing my own function with an implicit return type such as:

    export const Ellipsis = () => ({
      textOverflow: 'ellipsis',
      overflow: 'hidden',
      whiteSpace: 'nowrap'
    

    returns a similar typescript error:

    error TS2345: Argument of type '() => { textOverflow: string; overflow: string; whiteSpace: string; }' is not assignable to parameter of type 'Interpolation<ThemedStyledProps<HeadingProps, ThemeInterface>>'.
      Type '() => { textOverflow: string; overflow: string; whiteSpace: string; }' is not assignable to type 'ReadonlyArray<string | number | StyledComponentClass<any, any, any> | InterpolationFunction<Theme...'.
        Property 'find' is missing in type '() => { textOverflow: string; overflow: string; whiteSpace: string; }'.
    

    explicitly typing the return as Object causes:

    error TS2345: Argument of type '() => Object' is not assignable to parameter of type 'Interpolation<ThemedStyledProps<HeadingProps, ThemeInterface>>'.
      Type '() => Object' is not assignable to type 'ReadonlyArray<string | number | StyledComponentClass<any, any, any> | InterpolationFunction<Theme...'.
        Property 'find' is missing in type '() => Object'.
    

    Typing the return as any is a temporary work around, but I'm not sure what the correct return type should be, or if I'm missing something in between that converts the Object to a type that the interpolation function is compatible with.

    Again, thanks for your help!

    HI all,

    Just wondering if i have the same issue related to this one.
    I have created a components like:

    import * as React from 'react';
    import {MouseEventHandler} from 'react';
    interface IProps {
      className?: string;
      onClick?: MouseEventHandler<IProps>;
      menuMachineName: string;
    class Nav extends React.Component<any, IProps> {
      public render() {
        const {onClick, menuMachineName} = this.props;
        // some magic to get the right menu trough a api.   
        return (menuMachineName);
    export {Nav}

    And now i want to style the component with styled like this:

    import {Nav} from './Nav';
    const StyledNav = styled(Nav)`
       color: red;
    render() {
        return (<div><StyledNav menuMachineName="main" /></div>);
    

    And then i got this error:
    TS2559: Type '{ menuMachineName: "main"; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps<WithOptionalTheme...'.

    Typescript: ^2.6.1
    react: ^16.1.0
    styled-components: ^2.2.3

    Sorry to reopen an old issue, but still running into issues with this

    @Igorbek 's solution didn't work for me
    #824 (comment)

    @gargantuan this should work:

    function toInnerRef<T>(ref: undefined | React.Ref<T>): undefined | ((instance: T | null) => void) {
        if (!ref) {
            return undefined;
        if (typeof ref === 'string') {
            throw new Error('name refs are not supported.');
        return ref;
    

    This currently generates the following type error:

          TS2322: Type '((instance: T | null) => void) | RefObject<T>' is not assignable to type '((instance: T | null) => void) | undefined'.
      Type 'RefObject<T>' is not assignable to type '(instance: T | null) => void'.
        Type 'RefObject<T>' provides no match for the signature '(instance: T | null): void'.