styled-components / styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress 💅
https://styled-components.com
MIT License
40.11k stars 2.48k forks source link

Bug: DefaultTheme type allows any key, even when defining explicit type for theme #4254

Open narwold opened 3 months ago

narwold commented 3 months ago

Environment

❯ npx envinfo --system --binaries --npmPackages styled-components,babel-plugin-styled-components --markdown
Need to install the following packages:
envinfo@7.11.0
Ok to proceed? (y) y

## System:
 - OS: macOS 13.5.2
 - CPU: (10) arm64 Apple M1 Max
 - Memory: 49.94 MB / 32.00 GB
 - Shell: 5.9 - /bin/zsh
## Binaries:
 - Node: 20.10.0 - ~/.local/share/mise/installs/node/20.10.0/bin/node
 - npm: 10.2.3 - ~/.local/share/mise/installs/node/20.10.0/bin/npm
 - pnpm: 7.33.6 - ~/.local/share/mise/installs/node/20.10.0/bin/pnpm
 - Watchman: 2023.11.20.00 - /opt/homebrew/bin/watchman
## npmPackages:
 - styled-components: ^6.1.8 => 6.1.8

Reproduction

The previous DefinitelyTyped types used an empty object for DefaultTheme, which had the effect of allowing any keys until DefaultTheme was extended via https://styled-components.com/docs/api#create-a-declarations-file, at which time the theme ended up being strictly typed, and references to unknown keys threw an error in TS.

In the new v6 types, an index is being added ([key: string]: any;) that explicitly allows any key. There does not appear to be any way to remove/override this.

Steps to reproduce

  1. In https://codesandbox.io/p/sandbox/reverent-sara-hckdzp?file=%2Fsrc%2FApp.tsx%3A7%2C2, note that using styled-components v6, TS does not complain about the non-existing key.
  2. In https://codesandbox.io/p/sandbox/reverent-sara-forked-kfd7wm?file=%2Fsrc%2FApp.tsx%3A8%2C60, note that using v5 with DefinitelyTyped, TS DOES throw an error with the missing key. Note that you may not see the error until forking the CodeSandbox due to their read-only mode until doing so.

Expected Behavior

TS throws an error with unknown keys on the theme, if I have specified an explicit type for the theme via https://styled-components.com/docs/api#create-a-declarations-file

Actual Behavior

TS allows any key I want to reference, which does not enforce type safety on the theme.

rakestto commented 3 months ago

There are one difference between your gobal file. In the one you said that it works (v5) the globla file name is global.d.ts and in the other one is global.tsyou need to specify it as a declaration file

narwold commented 3 months ago

There are one difference between your gobal file. In the one you said that it works (v5) the globla file name is global.d.ts and in the other one is global.tsyou need to specify it as a declaration file

I had already tried that locally several times; that seems to have nothing to do with it. The fact that there was an inconsistency in the sandboxes was accidental. You'll see I've now changed it, and it does not solve the problem.

Also, it is reading the global type properly, because it will show the correct types if I use a known field (notice that "legitColor" gets shown as a string in both cases). The problem is the extra index that is being mixed in from the original type, so in the v6 sandbox an unknown type shows up as "any" whereas in the v6 sandbox it errors out as it should.

mosherc commented 3 months ago

Same issue as https://github.com/styled-components/styled-components/issues/4247

narwold commented 3 months ago

Same issue as #4247

I don't think the original #4247 is the same issue (but the replies are), because it mentions not being able to benefit from types at all in a SC (only the ThemeProvider). That is not the symptom here, as I get the types just fine; they are just too broad because they contain the any index.

tomfridental1 commented 1 month ago

Same issue here, Theme is typed via styled.d.ts file, the added types are indeed present but typescript not limiting the type to the added keys, and any key can be passed.

It seems like falling back to the DefaultTheme inside node modules when key is not present in the provided type.