我们使用自定义组件 (MySnackbarContent) 扩展了 SnackbarContent 组件:
export interface MySnackbarContentProps extends Omit<SnackbarContentProps, 'variant'> {
variant?: MyCustomVariant;
type?: MyCustomType;
banner?: boolean;
// ...
}
const MySnackbarContent = forwardRef<HTMLElement, MySnackbarContentProps>(props: MySnackbarContentProps, ref) => {
const { variant = 'normal', type = 'default', banner = false, ...other } = props;
const className = ...;
return <SnackbarContent ref={ref} className={className} {...other} />
}
这是我使用自定义 SnackbarContent 组件时遇到的错误:
类型 '{ type: "error" | 中缺少属性 'css' “默认”| “成功”|不明确的;消息:字符串;动作:元素; }',但在“Pick
”类型中是必需的。
我不明白为什么
css
属性在这里是一个问题,因为我们没有使用情感或样式组件(我们正在使用 JSS)。
奇怪的是,当我删除
forwardRef
时,所有类型都被正确检查。
缓解此问题的一种可能方法是在
css
中添加 MySnackbarContentProps
属性并将其设置为:css?: null
。由于某种原因, css
属性是必需的属性。不是 100% 确定为什么会出现这种情况。我在这里缺少什么?
编辑:根本原因的解释
尝试了解根本原因时,需要考虑三个部分。
首先,Typescript 允许增强任何类型,增强的结果将是不同定义中的属性的合并。例如下面的代码:
interface Person {
name: string;
}
interface Person {
age: number;
}
将与编写以下内容相同:
interface Person {
name: string;
age: number
}
此增强不需要位于同一模块/文件中;因此,项目中的任何模块(包括node_modules)都可以增强另一个模块中的任何类型)。
其次,Material UI 允许将所有 DOM 属性传递给它的许多组件。因此,它本质上是在很多组件中扩展了基础
React.DOMAttributes<T>
(例如 Paper 扩展了 React.DOMAttributes<HTMLDivElement>
)。
对我来说,我能够找到问题,因为我知道
css
是emotion
的属性,这是Storybook使用的;因此,我更深入地研究了情感的作用,并发现了以下内容:https://github.com/emotion-js/emotion/blob/31e610f2385d5a3dfd532b31f743e5f6b9fee43b/packages/react/types/index.d.ts#L99
因此,情感通过添加
可选
React.DOMAttributes<T>
属性来增强 css
。如果任何类型从此类型扩展,它们将有权访问 css
属性。这足以让我找出罪魁祸首。该库正在导出一个用于 Storybook 的实用程序(一些 Storybook 函数是从这些实用程序导入的)。从输出中删除该组件解决了问题。如果您使用的是 Storybook,请检查输出的包是否使用了任何 Storybook 组件。
我没有调查的一件事是,为什么
css
是强制性属性,尽管情感将道具作为可选属性传递。
感谢您的跟进,Gasim!
对我来说,根本问题也是由于 Storybook 与应用程序捆绑在一起引起的,因为我们使用的是带有
*.stories.tsx
扩展名的 Storybook 文件。
Typescript 加载我们设置中的所有 .tsx
文件,进而加载提到的全局 Emotion 道具增强 OP。
我必须将
"exclude": ["**/*.stories.tsx"]
添加到我们的 tsconfig.json
来修复它。
嗨,我面临同样的问题,但只是 ts 项目参考。在我的库中,我有一些故事书组件,但它们被排除在外,并且它们不会被我的任何 src 组件导入,甚至 vscode 用 NoTsconfig 标记所有这些 *.stories.tsx 文件,这里留下我的配置图像: