我有一个 monorepo,其中包含一个由样式组件构成的设计系统。在这个设计系统中,我有一个 Heading 组件,它采用“level”属性来调整标题的 CSS。
标题
export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
level: 'colossus' | 'uber' | 'hero' | '1' | '2' | '3' | '4' | '5'
}
export const Heading: React.FC<HeadingProps> = ({ level = '1', children, ...rest }) => {
return (
<HeadingStyled level={level} {...rest}>
{children}
</HeadingStyled>
)
}
使用
要使用这个 Heading 组件,我只需将一个 level
传递给它用于样式和 as
属性来调整呈现的 HTML。
<Heading as="h2" level="2">
Header 2
</Heading>
问题
当我使用这个组件时,我在 as
道具上收到了一个打字稿错误
Type '{ children: string; as: string; level: "2"; }' is not assignable to type 'IntrinsicAttributes & HeadingProps & { children?: ReactNode; }'.
Property 'as' does not exist on type 'IntrinsicAttributes & HeadingProps & { children?: ReactNode; }'.
我试过了:
export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
level: 'colossus' | 'uber' | 'hero' | '1' | '2' | '3' | '4' | '5'
as?: React.Element | JSX.Element | JSX.IntrinsicElements
}
答案 0 :(得分:3)
你就在附近! JSX.IntrinsicElements
是一个接口,它的 keys 是 HTML 标签的标签。它本身并不是所有 HTML 标签的联合。
这意味着你需要做的就是
interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
// ...
as?: keyof JSX.IntrinsicElements // Note the keyof!
}
现在 as
的签名被 TS 显示为:
(JSX attribute) HeadingProps.as?: "symbol" | "object" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 156 more ... | undefined
这意味着您的代码现在可以完全按预期工作
<Heading as="h2" level="2"> // No TS errors! ✅
Header 2
</Heading>