question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using TypeScript's React.ComponentType with Emotion 11 and /** @jsxImportSource @emotion/react */

See original GitHub issue

Description:

I’m upgrading a project from Emotion 10 to Emotion 11. There are some parts of the code that use a generic Prop type then use React.ComponentType to specify a component that uses those props. Ultimately something like this:

function example<Props>(Component: React.ComponentType<Props>, props: Props) {
    return <Component {...props} />;
}

With Emotion 11 and /** @jsxImportSource @emotion/react */, the props cannot be assigned to the component:

Type 'Props' is not assignable to type 'IntrinsicAttributes & WithConditionalCSSProp<PropsWithChildren<Props>> & Props & { children?: ReactNode; }'.
  Type 'Props' is not assignable to type 'WithConditionalCSSProp<PropsWithChildren<Props>>'.ts(2322)

From what I can gather, TypeScript can’t assign Props to WithConditionalCSSProp<Props> due to WithConditionalCSSProp being a conditional type. TS can’t handle something like the following, even though to the reader it seems intuitive X would be assignable to Output<X>:

type Output<T> = T extends string ? T : T;

function example<X>(input: X): Output<X> {
  // Type 'X' is not assignable to type 'Output<X>'
  return input;
}

Is there any workaround for this issue? I’m not sure if there’s a way I can fix React.ComponentType or there’s a fundamentally different approach I should be taking. Thanks!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:8
  • Comments:20 (13 by maintainers)

github_iconTop GitHub Comments

5reactions
stuartkeithcommented, Apr 16, 2021

It turns out the helper approach didn’t really work for me. I ended up manually asserting the type, using EmotionJSX.LibraryManagedAttributes directly. This means that the css prop is defined as any, which is not ideal, but I wasn’t able to come up with a better solution.

import { EmotionJSX } from '@emotion/react/types/jsx-namespace';

function example<Props>(Component: React.ComponentType<Props>, props: Props) {
  return <Component {...props as EmotionJSX.LibraryManagedAttributes<typeof Component, Props>} />;
}

I will close this issue for now. Thanks.

1reaction
stuartkeithcommented, Jan 23, 2021

I’ve found that manually extending the props type with Props & WithConditionalCSSProp<Props> fixes the issue:

function example<Props>(Component: React.ComponentType<Props>, props: Props & WithConditionalCSSProp<Props>) {
  return <Component {...props} />;
}

function ComponentWithClassName(props: { className?: string }) {
  ...
}

// Props generic is inferred as `{ className?: string }`,
// `props` variable is `{ className?: string; css?: Interpolation<Theme>; }`
example(ComponentWithClassName, { css: { color: 'red' } });

This makes sense to me - Props is still generic and inferred from the Component definition, but we’re telling TypeScript the props variable should be compatible with the Component instance.

So exporting a helper along the lines of type Helper<T> = T & WithConditionalCSSProp<T> is pretty straightforward, to enable props: Helper<Props> and avoid working with WithConditionalCSSProp directly. That seems promising and I can look into that more next week.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript - Emotion
@emotion/react. The easiest way to use the css prop with TypeScript is with the new JSX transform and the jsxImportSource TSConfig option (available...
Read more >
Using TypeScript's React.ComponentType with Emotion 11 ...
Description: I'm upgrading a project from Emotion 10 to Emotion 11. There are some parts of the code that use a generic Prop...
Read more >
What is the proper way to enable the css prop in Emotion 11 ...
If using the automatic runtime, you should be able to fix the issue by adding the following to your tsconfig.json .
Read more >
cannot find module '@emotion/react/jsx-runtime' or its ...
Describe the bug. I am using vite with preact-ts preset. Tried to install a react-specific library (chakra-ui). In development everything is okay, ...
Read more >
@emotion/react | Yarn - Package Manager
Simple styling in React. Install. yarn add @emotion/react. Usage. /** @jsx jsx */ import ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found