带有打字稿的 EmotionJS 不会将主题类型传递给样式化组件中的道具

EmotionJS with typescript doesn't pass theme type to props in styled components

emotion.d.ts

import '@emotion/react';

declare module '@emotion/react' {
    export interface Theme {
        colors: {
            primaryColor: string;
            accentColor: string;
        };
    }
}

App.tsx

import { Theme, ThemeProvider } from '@emotion/react';

const theme: Theme = {
    colors: {
        accentColor: 'hotpink',
        primaryColor: 'aqua',
    },
};
...

return (
<ThemeProvider theme={theme}>

...

Button.tsx

const StyledButton = styled.a`
    ${({ theme }) =>
        `background-color: ${theme.colors.accentColor};`
    }`;

tsconfig.json

{
    "compilerOptions": {
        "target": "es6",
        "allowSyntheticDefaultImports": true,
        "moduleResolution": "node",
        "sourceMap": true,
        "typeRoots": ["src/@types"],
        "jsx": "react",
        "strict": true,
        "strictNullChecks": true,
        "baseUrl": "./",
        "paths": {
            "*": ["src/@types/*"]
        }
    },
    "compileOnSave": false,
    "include": ["src/**/*"]
}
src
|=>@types
  |> emotion.d.ts
|=> components
|> App.tsx

属性 'colors' 在类型 'object' 上不存在。

是我做错了什么还是我看错了文档?

现在我正在通过将主题传递给样式构造函数来手动添加主题:


type StyledProps = Pick<ButtonProps, 'bgColor' | 'fColor'> & { theme: Theme };

const StyledButton = styled.a<StyledProps>`
...

删除传递的类型也无济于事。

似乎正确选择了 d.ts 文件,因为我可以使用 import { Theme } from "@emotion/react""@emtion/react" 导入正确的主题类型并使用它来键入 props.theme 在样式组件中

Repro

根据您提供的代码,我认为错误应该是:

Property 'accentColor' does not exist on type 'Theme'. // instead of object

无论如何,您的 Theme 对象现在由 colors 嵌套在顶层,因此您可以更改为:

const StyledButton = styled.a`
  ${({ theme }) =>
      `background-color: ${theme.colors.accentColor};` // `accentColor` is nested in `colors`
  }`;

请记住,您还需要通过 include 选项在 tsconfig.json 文件的构建过程中包含您定义的类型。

有关无法通过自定义类型文件覆盖 Theme 的更新

正如我所见,styled 类型仅使用来自 @emotion/reactTheme 对象,至少来自 ^11.0.0.

版本

简而言之,您必须将 @emotion/styled 更新到此版本 ^11.0.0 才能使其按预期工作:

{
  "dependencies": {
    // ...
    "@emotion/styled": "^11.0.0",
  }
}