Reputation: 61
I'm trying to implement animation in React + Typescript.
interface IImageProps {
frame: number
width: number
src: string
onLoad: () => void
}
const Image = styled.img`
transform: ${(props: IImageProps) => css`translate(0, -${props.frame * props.width}px)`};
`
This throws a warning in console:
styled-components.browser.esm.js:1507 Over 200 classes were generated for component styled.img.
Consider using the attrs method, together with a style object for frequently changed styles.
So I'm trying to use attrs
:
const Image = styled.img.attrs((props: IImageProps) => ({
style: { transform: `translate(0, -${props.frame * props.width}px)` },
}))``
now TS complains that:
Type '{ src: string; onLoad: () => void; width: number; frame: number; }' is not assignable to type 'IntrinsicAttributes & Pick<Pick<Pick<Pick<DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "src" | "width" | "children" | "style" | "title" | ... 255 more ... | "useMap"> & { ...; } & { ...; }, "src" | ... 259 more ... | "useMap"> & Partial<...>, "src" | ... 260 more ... | "useMap"> & { ...;...'.
Property 'frame' does not exist on type 'IntrinsicAttributes & Pick<Pick<Pick<Pick<DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "src" | "width" | "children" | "style" | "title" | ... 255 more ... | "useMap"> & { ...; } & { ...; }, "src" | ... 259 more ... | "useMap"> & Partial<...>, "src" | ... 260 more ... | "useMap"> & { ...;...'.
I can overcome that by casting const Image = ... `` as any
But I don't like that any
. Maybe it's an easy answer for someone familiar with styled components code...
Upvotes: 1
Views: 3665
Reputation: 4081
You will want to add the IImageProps
to the final tagged template call, to signal that those are the custom props that your Styled Component adds in addition to the <img>
props:
const Image = styled.img.attrs((props: IImageProps) => ({
style: { transform: `translate(0, -${props.frame * props.width}px)` },
}))<IImageProps>``
Note that you can also move the type annotation from the (props: IImageProps)
to the .attrs
type parameter:
const Image = styled.img.attrs<IImageProps>(props => ({
style: { transform: `translate(0, -${props.frame * props.width}px)` },
}))<IImageProps>``
That way, props
will be your custom interface plus all the built-in props for img
.
Upvotes: 5