twin.macro icon indicating copy to clipboard operation
twin.macro copied to clipboard

Stitches styled components return any type

Open redbaron76 opened this issue 2 years ago • 2 comments

All the components created by the Stitches's styled-components implementation return any type. So it seems that the Stitches component's types out-of-the-box feature is completely lost.

In others styled usages (Emotion, Styled-Components, ...) it is possible to type styled component through generics like this:

interface IStyle {
  green?: boolean;
  purple?: boolean;
...
}

const StyledButton = styled.button<IStyle>((props) => [
  tw`rounded text-xl...
...

Isn't it possible to adopt a similar approach using Stitches? Would it be possible? Thanks

redbaron76 avatar Sep 15 '21 07:09 redbaron76

You're supposed to use variants and then extract the prop type with React.ComponentPropsWithoutRef or React.ComponentPropsWithRef if needed.

The reason your component is typed any is because types/twin.d.ts from the examples repo is broken right now (at least I think it is). When I tried it StyledTags was any and that's why the styled import from twin was any (and that's why the components also ended up being any).

lboecker avatar Sep 19 '21 14:09 lboecker

Hi @redbaron76

the twin.d.ts is unfortunately broken, as @lboecker mentioned, it uses undefined types (AnyIfEmpty, CreateStyledComponent, so it becomes any.

For your example: I would do that more like this with stitches:

import tw, { styled } from 'twin.macro'
import type { VariantProps } from '@stitches/react'

const StyledButton = styled('button', {
  ...tw`rounded text-xl`,
  variants: {
    green: { true: tw`bg-green-600` },
    purple: { true: tw`bg-purple-600` }
   }
})

// has IntelliSense for variants
<StyledButton green>My Green Button</StyledButton>

// extract type of Variants
type IStyles = VariantProps<typeof StyledButton>

For typing purposes around Stitches, like variant type extraction consult the following: https://stitches.dev/docs/typescript.

I got the best overall type experience with the following twin.d.ts:

import type { CSS as StitchesCSS } from '@stitches/react'
import { config, css as cssStitches, styled as styledStitches } from '../stitches.config'

declare global {
  type CSS = StitchesCSS<typeof config>
}

declare module 'react' {
  // The css prop
  interface HTMLAttributes<T> extends DOMAttributes<T> {
    css?: CSS
    tw?: string
  }
  // The inline svg css prop
  interface SVGProps<T> extends SVGProps<SVGSVGElement> {
    css?: CSS
    tw?: string
  }
}

declare module 'twin.macro' {
  // The styled and css imports
  const styled: typeof styledStitches
  const css: typeof cssStitches
}

I was not able to get the styled.button syntax to work, however, I am fine with styled('button', {}) given the excellent type support I get.

nibtime avatar Feb 23 '22 23:02 nibtime

Check the example for the updated types.

ben-rogerson avatar Nov 15 '22 22:11 ben-rogerson