带有打字稿的 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/react
的 Theme
对象,至少来自 ^11.0.0
.
版本
简而言之,您必须将 @emotion/styled
更新到此版本 ^11.0.0
才能使其按预期工作:
{
"dependencies": {
// ...
"@emotion/styled": "^11.0.0",
}
}
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/react
的 Theme
对象,至少来自 ^11.0.0
.
简而言之,您必须将 @emotion/styled
更新到此版本 ^11.0.0
才能使其按预期工作:
{
"dependencies": {
// ...
"@emotion/styled": "^11.0.0",
}
}