eiv*_*dml 1 emotion typescript reactjs styled-components
我有一个BoxWithAs组件,定义如下:
const BoxWithAs = styled.div(\n {\n WebkitFontSmoothing: \'antialiased\',\n MozOsxFontSmoothing: \'grayscale\'\n // And more \xe2\x80\xa6\n }\n);\nRun Code Online (Sandbox Code Playgroud)\n一切都很好,但现在我想弃用来自 的默认道具之一@emotion/styled,特别是asprop.
我这样做了:
\ntype BoxWithAsType = typeof BoxWithAs;\ntype BoxProps = Omit<React.ComponentProps<BoxWithAsType>, \'as\'>;\n\n/**\n * Component that does it all.\n */\nconst Box = (props: BoxProps) => {\n return <BoxWithAs {...props}>{props.children}</BoxWithAs>;\n};\nRun Code Online (Sandbox Code Playgroud)\n它确实删除了道具...
\n\n...但现在组件本身丢失了所有StyledComponent类型信息。
我如何构建这个才能实现两者?我的最终目标是弃用该as道具,而是鼓励使用.withComponent(出于 Typescript 的原因)。
如果我们将鼠标悬停在上面,BoxWithAs我们会看到它是这种类型:
StyledComponent<{
theme?: Theme | undefined;
as?: React.ElementType<any> | undefined;
}, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>
Run Code Online (Sandbox Code Playgroud)
所以你可以这样做:
type BoxWithoutAs = StyledComponent<{
theme?: Theme | undefined;
}, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
const Box = BoxWithAs as BoxWithoutAs;
Run Code Online (Sandbox Code Playgroud)
但这种类型确实又长又笨重。我们尝试简化它并使其变得更干燥:
StyledComponent<Omit<React.ComponentProps<BoxWithAsType>, "as">, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>
Run Code Online (Sandbox Code Playgroud)
这并没有好多少,甚至可以说更糟。如果我们能够推断出其他两个参数而不是让我们完整地输入它,那么会有帮助。
我们可以使用辅助实用程序类型:
type OmitProps<Component, Props extends PropertyKey> = Component extends StyledComponent<infer P, infer S, infer J> ? StyledComponent<Omit<P, Props>, S, J> : never;
Run Code Online (Sandbox Code Playgroud)
现在,TypeScript 将为我们推断其他两个参数,我们可以使用它Omit<P, Props>来省略任何我们想要的 props。
const Box = BoxWithAs as OmitProps<BoxWithAsType, "as">;
Run Code Online (Sandbox Code Playgroud)
似乎工作正常!
| 归档时间: |
|
| 查看次数: |
1280 次 |
| 最近记录: |