我',试图创建一个模仿本地html元素的react组件。
允许使用有效的html属性
示例:
type TAtt = {
[key: string]: React.HTMLAttributes<HTMLElement>;
};
const NavAnyValidAttribute: React.FC<TAtt> = props => {
const { children, ...therest } = props;
return <nav {...therest}>{children}</nav>;
};
<NavAnyValidAttribute className="x">some children</NavAnyValidAttribute>;
类型'string'与类型'HTMLAttributes'没有共同的属性。(2559) input.tsx(135,3):预期的类型来自此索引签名。
type TProps = TAtt & {
TagName: string; //keyof JSX.IntrinsicElements - also doesn't work!;
}
const Tag: React.FC<TProps> = ({ TagName, children, ...props }) =>
React.createElement(TagName, props, children);
const Nav = <Tag {...{ TagName: 'nav' }} />;
错误:输入'{TagName:string; }”不可分配给“ TAtt”类型。 属性“ TagName”与索引签名不兼容。 类型“字符串”与类型“ HTMLAttributes”没有共同的属性。ts(2322)
任何帮助表示赞赏。 谢谢
答案 0 :(得分:0)
好的,我已经创建了一个解决方案。
我敢肯定有更好的方法,但是为了保持严格,并允许将此组件传递给另一个未知的组件处理程序,我必须确保我返回了Component
我还必须确保我拥有严格的TagName:React.ElementType。或“ JSX.IntrinsicElements键”。不确定哪个更合适。但以下两种方法都必须使用相同的方法。
我还必须将GetTagAsComp方法作为同一组件TagAsComp的成员返回。
如果有任何比较简单的方法,请随时添加。
import React from 'react';
type TElem = React.ElementType; // OR keyof JSX.IntrinsicElements;
// Might have to extend this for specific element attributes - see
// - https://www.saltycrane.com/cheat-sheets/typescript/react/latest/
type TAtt = React.HTMLAttributes<HTMLElement>;
type TCreateElement = {
TagName: TElem;
props: TAtt;
};
const CreateElement: React.FC<TCreateElement> = ({ TagName, props, children }) =>
React.createElement(TagName, props, children);
// technically this is a hoc, so would use prefix - with
// but it doesnt name well
// This existing name: TagAsComp is better describing what it is in shorthand - Tag as a component.
const TagAsComp = (TagName: TElem): React.ComponentType<any> => {
const GetTagAsComp: React.FC<TAtt> = props => {
const { children } = props;
return <CreateElement {...{ TagName, props, children }} />;
};
return GetTagAsComp;
};
export default TagAsComp;
// Usecase:
// const Tag = TagAsComp('div')
// <Tag onClick={doThing} className="hello" data-x="extra"> Some children </Tag>
对于我的用例,我想将其传递给样式化的组件,如下所示: 看看我的其他帖子:
const Nav = Style(TagAsComp('div'), theme);
虽然上面的解决方案可以回答我最初的问题,并且可能对其他用例也很有帮助。
我现在希望它更优雅:
const StyleNav = (props: TTheme): StyledComponent<'nav', {}> => styled.nav`
background: ${props.grey1};
display: block;
`;