nasheomirro / react-polymorphed

A set of types to help easily create fast polymorphic components.
MIT License
24 stars 3 forks source link

String concat/Template Literals throw TypeErrors #8

Closed mririgoyen closed 11 months ago

mririgoyen commented 11 months ago

When utilizing a templated string for as, TypeScript throws an error.

<Typography
  as={`h${startHeadingLevel}`}
/>
Type '`h${string}`' is not assignable to type '((string | ComponentClass<any, any> | FunctionComponent<any>) & ElementType<any>) | undefined'.

The weird things is the "type" of h${string}... That's not a type and a mouseover of the template shows "string" in VSCode.

Moving it out to it's own variable causes the same issue, with a more sane TS error:

Type 'string' is not assignable to type '((string | ComponentClass<any, any> | FunctionComponent<any>) & ElementType<any>) | undefined'.

Casting the variable as an React.ElementType works, but I do not wish to force the users of my component to have to cast all their templated strings to work.

Any ideas?

nasheomirro commented 11 months ago

Hey @mririgoyen, so a few things here, the as prop expects either a Component or IntrinsicElements type. the former is our custom components (class or functional) and the latter is the various HTML tags that we use (ex. "p", "h1", "button", etc.). So with that we now know that the problem is that we're assigning a string to our as prop which won't do,

one other thing is template literal types actually do exist! That's why we see the first error be h${string} which means that that specific template literal doesn't match with any of the types expected by the as prop. If we were to change the type of startHeadingLevel from string to 1 | 2 | 3 | 4 | 5 | 6 we can see this working.

Playground here