emotion icon indicating copy to clipboard operation
emotion copied to clipboard

Typescript error (TS2464): Computed property

Open ghost opened this issue 5 years ago • 13 comments

  • gatsby-plugin-emotion version: 4.0.6
  • react version: 16.8.4

Relevant code:

const StyledLink = styled(Link)({...});

const MobileLinkContainer = styled("div")({
  ... 
  [StyledLink]: {
    padding: "1rem"
  }
});

What happened: I get an error: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. ts(2464) at the [StyledLink] line

Suggested solution: A workaround is to use [StyledLink as any].

ghost avatar Mar 15 '19 20:03 ghost

I have the same issue and was able to work around it for now by explicitly returning :any from the child element.

const StyledCheckbox: any = styled.input(({ theme }) => ({}));

const CheckboxLabel = styled.label(({ theme }) => ({
  [StyledCheckbox]: {}
}));

mwarger avatar Mar 19 '19 19:03 mwarger

We've been experiencing the same issue for our projects, Rather than typing the StyledCheckbox to any, you can instead do it in the directly within the computed property. This way you keep nice type introspection for the rest of your application:

const StyledCheckbox = styled.input(({ theme }) => ({}));

const CheckboxLabel = styled.label(({ theme }) => ({
  [StyledCheckbox as any]: {}
}));

luk707 avatar Mar 21 '19 16:03 luk707

Noticing this still. +1 to get it fixed.

B-Stewart avatar Jul 24 '19 18:07 B-Stewart

I believe this has been fixed already, but if not - please raise it again. Thanks for understanding.

Andarist avatar Oct 29 '19 08:10 Andarist

@Andarist This is still an issue in v10.0.27.

jsonmaur avatar Mar 21 '20 03:03 jsonmaur

@Andarist +1 on v10.0.27 with Next.js

praneetrohida avatar Apr 22 '20 07:04 praneetrohida

Anyone got anything on this? this is still an issue.

chadlavi avatar Mar 04 '21 23:03 chadlavi

Still getting this on version 11.7.1

Pearce-Ropion avatar Feb 14 '22 04:02 Pearce-Ropion

Please always try to share a repro case in a runnable form - either by providing a git repository to clone or a codesandbox. OSS maintainers usually can't afford the time to set up the repro, even if exact steps are given.

Andarist avatar Feb 14 '22 08:02 Andarist

Still getting this on version 11.9.0

lucaslz2020 avatar May 02 '22 14:05 lucaslz2020

Minimal repro: https://codesandbox.io/s/emotion-1275-w3dkqd?file=/src/App.tsx It encounters an error at runtime since @emotion/babel-plugin is not used, but it does demonstrate the TypeScript compilation error.

I don't see any way to "fix" this issue. The TypeScript error is totally legit, since TypeScript has no way to know about the transformation applied by @emotion/babel-plugin. I think we should just add a note to the documentation about component selectors to say that as any is necessary in this case.

@Andarist Unless you know how to fix this?

srmagura avatar May 02 '22 14:05 srmagura

I don't see any way to "fix" this issue. The TypeScript error is totally legit, since TypeScript has no way to know about the transformation applied by @emotion/babel-plugin

Right, so we just assume at the type-level that this transformation is always applied and we add a "fake trait" to our StyledComponent interface: https://github.com/emotion-js/emotion/blob/26e4e3e8b68479f0e3cb8fbec723da47afd6ac98/packages/styled/types/base.d.ts#L41

This allows styled components to be interpolated into our template strings~. But it doesn't allow us to use them as computed properties in the object syntax. We could make it work if we would add & string to those types but that could complicate inheritance and "wrapping" (like styled(styled.div({}))), so unless somebody would try this change and add good type-level tests to cover it I don't think it's something I would explore myself.

The workaround I usually do to cover this is just this:

const MobileLinkContainer = styled.div({
-  [StyledLink]: {
+  [String(StyledLink)]: {
    padding: "1rem"
  }
});

It's simple, explicit and effective.

Andarist avatar May 02 '22 17:05 Andarist

const MobileLinkContainer = styled.div({
  [`${StyledLink}`]: {
    padding: "1rem"
  }
});

upd: https://github.com/emotion-js/emotion/issues/501

alexicum avatar Jun 28 '23 09:06 alexicum