Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

types: improve the types returned by styled #32

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

RJWadley
Copy link
Contributor

@RJWadley RJWadley commented Feb 2, 2025

improvements, in no particular order:

  • style props are filtered from the component props
    if we were to use a style prop that already existed on the component, our type would not reflect it
const Sample= styled('div', ({ onClick }: { onClick: string }) => ({
  color: onClick,
}))

in this example, previously onClick was MouseEventHandler<HTMLDivElement> & string, but because style props are filtered, a more correct type is just string

  • style props are not allowed to break the component type
    because style props are filtered, if a required component prop and a style prop share a name we now get a type error
const component = ({
  className,
  color,
}: {
  className: string
  color: number
}) => <div className={className}>{color}</div>

// @ts-expect-error extending with color would make color always undefined, but color must be a number
const extended = styled(component, ({ color }: { color: string }) => ({
  color,
}))
  • extra properties are not allowed
    previously, if style props was a function our component props were expanded to Record<string, unknown> which would let us add incorrect props
const Extended = styled(
  Extended2,
  ({ color }: { color: string }) => ({
    color,
  })
)

const test= (
  <Extended
    className="abc"
    // @ts-expect-error name does not exist on type, but previously was allowed anyway
    name="abc"
  />
)
  • generic types are preserved
    this also adds support for generic type propagation, so if we style a generic function component the generic will be preserved. do note that generic class components will not be propagated, only generic function components.
const Component = <SomeText extends string>({
  id,
  className,
}: {
  id: `id-${SomeText}`
  className?: string
}) => <div></div>
const Extended = styled(Component, { color: 'red' })

const example= (
  <>
    <Component<'abc'> id="id-abc" />
    {/* our generic is preserved! previously was a type error */}
    <Extended<'abc'> id="id-abc" color="red" />
  </>
)

Copy link

vercel bot commented Feb 2, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
restyle ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 3, 2025 5:33pm

@RJWadley
Copy link
Contributor Author

RJWadley commented Feb 3, 2025

test is failing due to some issue related to corepack and the npm registry

I could find some workaround right now but I'd rather just wait for that to settle a bit

EDIT: all good now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant