从情感风格的组件中省略特定的道具?
Omit specific prop from an emotion styled component?
我有一个 BoxWithAs
组件,定义如下:
const BoxWithAs = styled.div(
{
WebkitFontSmoothing: 'antialiased',
MozOsxFontSmoothing: 'grayscale'
// And more …
}
);
很好,但现在我想弃用来自 @emotion/styled
的默认道具之一,特别是 as
道具。
我这样做了:
type BoxWithAsType = typeof BoxWithAs;
type BoxProps = Omit<React.ComponentProps<BoxWithAsType>, 'as'>;
/**
* Component that does it all.
*/
const Box = (props: BoxProps) => {
return <BoxWithAs {...props}>{props.children}</BoxWithAs>;
};
它确实删除了道具...
...但现在组件本身丢失了所有 StyledComponent
类型信息。
我如何构建它才能实现两者?我的最终目标是弃用 as
道具,而是鼓励使用 .withComponent
(出于 Typescript 原因)。
如果我们将鼠标悬停在 BoxWithAs
上,我们会看到它属于这种类型:
StyledComponent<{
theme?: Theme | undefined;
as?: React.ElementType<any> | undefined;
}, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>
所以你可以这样做:
type BoxWithoutAs = StyledComponent<{
theme?: Theme | undefined;
}, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
const Box = BoxWithAs as BoxWithoutAs;
但是那种真的又长又笨重。我们尝试简化它并使它更干燥:
StyledComponent<Omit<React.ComponentProps<BoxWithAsType>, "as">, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>
这并没有好多少,而且可以说更糟。如果我们可以推断出其他两个参数而不是让我们输入完整的参数,那将会有所帮助。
我们可以使用辅助实用程序类型:
type OmitProps<Component, Props extends PropertyKey> = Component extends StyledComponent<infer P, infer S, infer J> ? StyledComponent<Omit<P, Props>, S, J> : never;
现在,TypeScript 会为我们推断出其他两个参数,我们可以使用 Omit<P, Props>
来省略我们希望的任何道具。
const Box = BoxWithAs as OmitProps<BoxWithAsType, "as">;
似乎工作正常!
我有一个 BoxWithAs
组件,定义如下:
const BoxWithAs = styled.div(
{
WebkitFontSmoothing: 'antialiased',
MozOsxFontSmoothing: 'grayscale'
// And more …
}
);
很好,但现在我想弃用来自 @emotion/styled
的默认道具之一,特别是 as
道具。
我这样做了:
type BoxWithAsType = typeof BoxWithAs;
type BoxProps = Omit<React.ComponentProps<BoxWithAsType>, 'as'>;
/**
* Component that does it all.
*/
const Box = (props: BoxProps) => {
return <BoxWithAs {...props}>{props.children}</BoxWithAs>;
};
它确实删除了道具...
...但现在组件本身丢失了所有 StyledComponent
类型信息。
我如何构建它才能实现两者?我的最终目标是弃用 as
道具,而是鼓励使用 .withComponent
(出于 Typescript 原因)。
如果我们将鼠标悬停在 BoxWithAs
上,我们会看到它属于这种类型:
StyledComponent<{
theme?: Theme | undefined;
as?: React.ElementType<any> | undefined;
}, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>
所以你可以这样做:
type BoxWithoutAs = StyledComponent<{
theme?: Theme | undefined;
}, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
const Box = BoxWithAs as BoxWithoutAs;
但是那种真的又长又笨重。我们尝试简化它并使它更干燥:
StyledComponent<Omit<React.ComponentProps<BoxWithAsType>, "as">, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>
这并没有好多少,而且可以说更糟。如果我们可以推断出其他两个参数而不是让我们输入完整的参数,那将会有所帮助。
我们可以使用辅助实用程序类型:
type OmitProps<Component, Props extends PropertyKey> = Component extends StyledComponent<infer P, infer S, infer J> ? StyledComponent<Omit<P, Props>, S, J> : never;
现在,TypeScript 会为我们推断出其他两个参数,我们可以使用 Omit<P, Props>
来省略我们希望的任何道具。
const Box = BoxWithAs as OmitProps<BoxWithAsType, "as">;
似乎工作正常!