styled-components: Typescript checking error

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

interface ISVGIconProps {
  color: string,
  children: React.ReactNode,
  titleAccess: boolean,
  size: string,
  viewBox: string
}

const SVG = styled.svg`
  display: inline-block;
  fill: currentColor;
  height: ${(p: any) => p.size};
  width: ${(p: any) => p.size};
  user-select: none;
  flex-shrink: 0;
  color: ${(p: any) => p.color};
  transition: ${(p: any) => p.theme.transition.create('fill', { duration: p.theme.transition.durations.shorter })};
`

export const SVGIcon: React.StatelessComponent<ISVGIconProps> = (props) => {
  const { titleAccess, children, size, ...others } = props

  return (
    <SVG
      width={size}
      height={size}
      // @ts-ignore
      size={size} // <--- this is the issue
      focusable="false"
      aria-hidden={titleAccess ? 'false' : 'true'}
      {...others}
    >
      {titleAccess ? <title>{titleAccess}</title> : null}
      {children}
    </SVG>
  )
}

SVGIcon.defaultProps = {
  color: 'inherit',
  size: '1.5em',
  viewBox: '0 0 24 24'
}

[ts] Property 'size' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps<SVGProps<SVGSVGEl...'.

Basically any attribute that do not belongs to specific element (whatever that means because after custom element we do not need to do data- anymore but I guess make sense to the old elements?!)

Typescript will complains that any extra attribute I add for the propose of using it in my styled component it will rise this issue.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 22 (3 by maintainers)

Most upvoted comments

@DogPawHat no joke

npm uninstall typescript

I gave up to Typescript, productivity is more valuable for me than preventing issues that I do not face.

No more Typescript, best scenario flow for props validation and I am thinking on using prop-types for that even.

The TypeScript fix for this issue has been merged into Master and it can be used with the next npm version. Any example guys from the style-components team to fix the IntrinsicAttributes... error?

Ok, I looked into this, it’s fixed as far as styled-components are concerned, but there’s some issues with Typescript.

Bascilly, styled-components already has this:

https://github.com/Microsoft/TypeScript/issues/11947

export interface ThemedStyledFunction<P, T, O = P> {
  (strings: TemplateStringsArray, ...interpolations: Interpolation<ThemedStyledProps<P, T>>[]): StyledComponentClass<P, T, O>;
  <U>(strings: TemplateStringsArray, ...interpolations: Interpolation<ThemedStyledProps<P & U, T>>[]): StyledComponentClass<P & U, T, O & U>;
  attrs<U, A extends Partial<P & U> = {}>(attrs: Attrs<P & U, A, T>): ThemedStyledFunction<P & A & U, T, O & U>;
}

where U could be used to define additional prop types:

interface MyProps {
    primary: boolean;
    // etc...
}

const MyButton = styled.button<MyProps>`
  color: ${props => props.primary ? 'white' : 'red'}
`

Unfortunaly, this syntax doens’t work, and the issue below has been open for over a year:

https://github.com/Microsoft/TypeScript/issues/11947

So I don’t know when that will get fixed.


That said, usually this works:

interface MyProps {
    primary: boolean;
    // etc...
}

const MyButton = styled.button`
  color: ${(props: MyProps) => props.primary ? 'white' : 'red'}
`

at least on TS 2.6.2. your (p: any) should otherwise be fine, I think.

@philpl Issue #630 provides some more context.

styled-components does not provide any way to extend the prop typings of built-ins that use tagged template literals syntax.

TypeScript currently offers no way to pass a generic type interface to a tagged template literal function, so a wrapper function (like the one found in styled-components-ts) that takes a generic is the only workaround that exists right now.

Perhaps this wrapper function could be implemented as part of styled-components so an additional library isn’t needed, but the real solution for this needs to come from Typescript.

Hey guys, we were able to get this working via two ways. One way works now but isn’t the official way forward, the other way is the official way forward but is broken until the next TypeScript release (2.9.2)

The interface to allow us to use mb margin-bottom shortcut somewhere:

import styled from "styled-components";
import { space } from "styled-system";
interface HasMarginBottomStyledSystemProps {
    mb?: number;
}

Example usage (goal is to have it work w/o TypeScript errors):

<StyledH5 mb={0}>
    Hello World!
</StyledH5>

The first way that works now:

let StyledH5 = styled<HasMarginBottomStyledSystemProps, any>("h5")`
   ${space};
`;

The future way that will work soon:

let StyledH5 = styled.h5<HasMarginBottomStyledSystemProps>`
   ${space};
`;

You can track the status of fix for future way here (note the related issues at bottom): https://github.com/Microsoft/TypeScript/issues/24449

  • Credit to @robophred for helping me work through the TS syntax issues.

I’m not sure if this is related, but as far as I can tell, there is a bug in the example implementation of styled-components with TypeScript given here https://www.styled-components.com/docs/api#typescript.

I have constructed my file as per the example, however there are two things preventing me to use this as is.

The problematic part of the code is here:

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

export { css, injectGlobal, keyframes, ThemeProvider, withTheme };
export default styled;
  1. The linter complains about ThemeProvider:
Exported variable 'ThemeProvider' has or is using name 'React.ComponentClass' from external module ".../@types/react/index" but cannot be named.

If I add the import I need to add a @ts-ignore to keep the compiler happy. This is now working when used inside the same codebase. However, I’m using this as a separate component library, which leads to the second issue.

  1. The generated typings file (theme.d.ts) that I need to use the library in other projects contains the following code snippet:
declare const styled: styledComponents.ThemedBaseStyledInterface<ThemeInterface>, css: styledComponents.ThemedCssFunction<ThemeInterface>, injectGlobal: (strings: TemplateStringsArray, ...interpolations: styledComponents.SimpleInterpolation[]) => void, keyframes: (strings: TemplateStringsArray, ...interpolations: styledComponents.SimpleInterpolation[]) => string, ThemeProvider: React.ComponentClass<styledComponents.ThemeProviderProps<ThemeInterface>>, withTheme: <P extends {
    theme?: ThemeInterface | undefined;
}>(component: React.ComponentClass<P> | React.StatelessComponent<P>) => React.ComponentClass<Pick<P, ({ [P in keyof P]: P; } & {
    theme: never;
} & {
    [x: string]: never;
})[keyof P]> & {
    theme?: ThemeInterface | undefined;
}>;

This causes a bunch of errors along the lines of:

Type '({ [P in keyof P]: P; } & { theme: never; }[keyof P]' is not assignable to type '"theme"'.

I’m not ready to give up on TypeScript yet as it has a bunch of benefits, but it’s definitely killing productivity with issues such as this.

styledComponentWithProps from styled-components-ts just returns what you pass in with types, so its doen’t add much beyond fixing this issue. It might still be the best fix until Microsoft/TypeScript#11947 gets fixed.

@yordis have you had any luck with your issues?

@nderscore @alveshelio wait, sorry, why is styled-components-ts a thing? 😅If there are any fixes to our typings, we’d really prefer those to be PR’d and merged here 😉 so is there something we can workout and improve instead of a separate package?

cc @jacob-ebey, @styled-components/typers

Having a similar issue here