省略情感风格组件中的特定道具?

eiv*_*dml 1 emotion typescript reactjs styled-components

我有一个BoxWithAs组件,定义如下:

\n
const BoxWithAs = styled.div(\n  {\n    WebkitFontSmoothing: \'antialiased\',\n    MozOsxFontSmoothing: \'grayscale\'\n    // And more \xe2\x80\xa6\n  }\n);\n
Run Code Online (Sandbox Code Playgroud)\n

一切都很好,但现在我想弃用来自 的默认道具之一@emotion/styled,特别是asprop.

\n

我这样做了:

\n
type 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};\n
Run Code Online (Sandbox Code Playgroud)\n

它确实删除了道具...

\n

在此输入图像描述

\n

...但现在组件本身丢失了所有StyledComponent类型信息。

\n

在此输入图像描述

\n

我如何构建这个才能实现两者?我的最终目标是弃用该as道具,而是鼓励使用.withComponent(出于 Typescript 的原因)。

\n

moc*_*cha 5

如果我们将鼠标悬停在上面,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)

似乎工作正常!

操场

  • 这就是为什么我们不应该使用 JavaScript。人们通常利用动态类型和怪癖来编写更短但意图不明确的代码,这真是一团糟。这又是为了什么?一个网站?让我们都使用编译为 WASM 的语言。 (3认同)
  • 我想当你查看时间戳时,它看起来像是 50,但实际上我花了 45 来做其他工作。诚然,我对劳动力了解不多,因为我只是一个做 Stack Overflow 而不是做功课的高中生。尽管我同意 TypeScript 很快就会变得冗长,而且它主要是炒作,但它仍然是我仍然想使用的工具。与任何其他工具一样,您花时间学习它,然后您可以在以后使用它节省更多时间。 (3认同)