There have been some recent developments and with a new version of Typescript (eg. 3.0.1) and styled-components (eg. 3.4.5) there's no need for a separate helper. You can specify the interface/type of your props to styled-components directly.
interface Props {
onPress: any;
src: any;
width: string;
height: string;
}
const Icon = styled.Image<Props>`
width: ${p => p.width};
height: ${p => p.height};
`;
and if you want to be more precise and ignore the onPress
const Icon = styled.Image<Pick<Props, 'src' | 'width' | 'height'>>`
width: ${p => p.width};
height: ${p => p.height};
`;
Answer from elnygren on Stack Overflow
» npm install @types/styled-components
reactjs - TypeScript with styled-components - Stack Overflow
typescript - How to add types do styled components - Stack Overflow
How do I provide props to styled elements in Typescript?
`as` prop of styled components in TypeScript
Videos
There have been some recent developments and with a new version of Typescript (eg. 3.0.1) and styled-components (eg. 3.4.5) there's no need for a separate helper. You can specify the interface/type of your props to styled-components directly.
interface Props {
onPress: any;
src: any;
width: string;
height: string;
}
const Icon = styled.Image<Props>`
width: ${p => p.width};
height: ${p => p.height};
`;
and if you want to be more precise and ignore the onPress
const Icon = styled.Image<Pick<Props, 'src' | 'width' | 'height'>>`
width: ${p => p.width};
height: ${p => p.height};
`;
The easiest way as styled-components docs said:
import styled from 'styled-components';
import Header from './Header';
const NewHeader = styled(Header)<{ customColor: string }>`
color: ${(props) => props.customColor};
`;
// Header will also receive props.customColor
import React from "react";
import styled from "styled-components";
interface Props {
name: string;
className?: string;
}
const NonStyledIcon: React.SFC<Props> = ({ name, className, ...props }) => (
<i className={`material-icons ${className}`} {...props}>
{name}
</i>
);
const Icon = styled(NonStyledIcon)`
font-size: ${props => props.theme.sizeLarger};
`;
export default Icon;
As per the styled-components TypeScript docs: when defining a component you will need to mark className as optional in your Props interface
Here's a comprehensive approach using Styled Components v5 with React Native that will work with plain React as well. If you're not using a theme you can skip to the StyledProps section at the bottom.
Define your theme type.
// MyTheme.ts export type MyTheme = { colors: { primary: string; background: string; }; };Use the type on your themes.
// themes.ts export const LightTheme: MyTheme = { colors: { primary: 'white', background: 'white', }, }; export const DarkTheme: MyTheme = { colors: { primary: 'grey', background: 'black', }, };Use declaration merging to "merge" the MyTheme type into Styled Components default theme.
// styled.d.ts import 'styled-components'; import { MyTheme } from '../src/themes/MyTheme'; declare module 'styled-components' { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface DefaultTheme extends MyTheme {} }
OK, cool. The theme prop is correctly typed.
What about the components themselves?
Wrap your specific component props in the
StyledPropstype.import { StyledProps } from 'styled-components'; import styled from 'styled-components/native'; type MyViewProps = StyledProps<{ backgroundColor?: string; isAlert?: boolean; }>; const MyView = styled.View( (props: MyViewProps) => ` background-color: ${props.backgroundColor || props.theme.colors.background}; color: ${props.isAlert ? red : props.theme.colors.primary} `, );
In this example both props.backgroundColor and props.theme.colors.background will auto-complete. When you update MyTheme type or the specific component type it should just work.


It's not working due to this @types/styled-components issue -> link
TypeScript is complaining because your Link component that comes from react-router requires you to specify a to prop. I am not sure what you are trying to achieve, but Link should already render as an <a /> tag.
If you are willing to render a link to, let's say, an external website, you probably don't want to use a styled(Link), but a styled.a.
If you worry about repeating your style for both the styled(Link) and styled.a, you'd probably want to write a reusable button style using the css helper function and include it in both of your styled components.
Unfortunately, I believe it is the only option for now, as I have been in a similar case, and tried using as={Link} on a styled.a and TypeScript complains about unrecognised props. I believe that the implementation of the polymorphic as prop on TypeScript is not fully functional so there might be a fix later on.
I am trying to do this:
import React from 'react'
import styled, { CSSProperties, useTheme } from 'styled-components'
import { Theme } from './styles'
import useProps from './useProps'
export type BasicInputPropsType<T> = T | Array<T>
export type FactoryStyledPropsType = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
styledProps: any
}
export type InputPropsFunctionType<I, T> = (props: I) => T
export type InputPropsType<T, I> = T extends Function
? InputPropsFunctionType<I, T>
: T
export default function FactoryFactory<T>(
as: string,
serializer: (theme: Theme, props: T) => CSSProperties,
) {
return function Factory<I>(inputProps: InputPropsType<T, I>) {
const isPropsFunction = typeof inputProps === 'function'
const Styled = styled.div<FactoryStyledPropsType>(
props => props.styledProps,
)
function Component(props: I) {
const actualProps = isPropsFunction
? (inputProps as InputPropsFunctionType<I, T>)(props)
: props
const theme = useTheme()
const { styledProps, elementProps } = useProps(
actualProps,
theme,
serializer,
)
return (
<Styled
{...elementProps}
styledProps={styledProps}
/>
)
}
Component.toString = Styled.toString
return Component
}
}Essentially that styledProps, it should return what the styled component expects, but I can't figure out how to type it. I am looking at this type definition:
export interface ThemedStyledFunctionBase<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
T extends object,
O extends object = {},
A extends keyof any = never
> {
(first: TemplateStringsArray): StyledComponent<C, T, O, A>;
(
first:
| TemplateStringsArray
| CSSObject
| InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>>,
...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>>>
): StyledComponent<C, T, O, A>;
<U extends object>(
first:
| TemplateStringsArray
| CSSObject
| InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>,
...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>>
): StyledComponent<C, T, O & U, A>;
}But that is way too complex, I am not sure what to do. What is the type I need to specify for my styledProps?