简体   繁体   English

JS/TS: object 解构

[英]JS/TS: object destructuring

i've a variable named props .我有一个名为props的变量。 The type extends from VariantTheme , VariantSize , VariantGradient , & React.DOMAttributes<HTMLOrSVGElement>该类型扩展自VariantThemeVariantSizeVariantGradientReact.DOMAttributes<HTMLOrSVGElement>

Then i want to make one more variable, let say htmlProps .然后我想再做一个变量,比如说htmlProps I want to fill the htmlProps from props .我想从props填充htmlProps I don't want it filled with a foreign props other than listed on React.DOMAttributes<HTMLOrSVGElement> .除了在React.DOMAttributes<HTMLOrSVGElement>上列出的以外,我不希望它充满外国道具。 Then spread the filtered prop into react component.然后将过滤后的道具传播到反应组件中。

Here the not working code:这里不工作的代码:

export interface Props
    extends
        VariantTheme,
        VariantSize,
        VariantGradient,
        React.DOMAttributes<HTMLOrSVGElement>
{
    tag?     : keyof JSX.IntrinsicElements
    classes? : string[]
}
export default function Element(props: Props) {
    const elmStyles     = styles.useStyles();

    // themes:
    const variTheme     = useVariantTheme(props);
    const variSize      = useVariantSize(props);
    const variGradient  = useVariantGradient(props);



    const Tag       = (props.tag ?? 'div');
    const htmlProps = props as React.HTMLAttributes<HTMLOrSVGElement>; // not working! Still containing strange props from VariantTheme, VariantSize, tag, classes, ...
    return (
        <Tag {...htmlProps}
            className={[
                elmStyles.main,
                
                // themes:
                variTheme.class,
                variSize.class,
                variGradient.class,

                ...(props.classes ?? []),
            ].filter((c) => !!c).join(' ')}
        >
            {(props as React.PropsWithChildren<Props>)?.children}
        </Tag>
    );
};

Do you have an idea to fix my code?你有想法修复我的代码吗?

@spender already gave you the answer. @spender 已经给你答案了。 Typescript only exists at compile time and what you are really doing is telling the compiler that props is now of type React.HTMLAttributes<HTMLOrSVGElement> , but you are still responsible on how the props are composed. Typescript 仅在编译时存在,您真正要做的是告诉编译器 props 现在是React.HTMLAttributes<HTMLOrSVGElement>类型,但您仍然对props的组成方式负责。 In sum typescript does not alter how your javascript code works, it only helps you find mistakes at compile time.总之,typescript 不会改变您的 javascript 代码的工作方式,它只会帮助您在编译时发现错误。

One solution for your use case is to have htmlProps as a property of props and then spread these to Tag .您的用例的一种解决方案是将htmlProps作为props的属性,然后将它们传播到Tag

export interface Props
    extends
        VariantTheme,
        VariantSize,
        VariantGradient
{
    tag?     : keyof JSX.IntrinsicElements
    classes? : string[],
    htmlProps: React.DOMAttributes<HTMLOrSVGElement>, // dom attributes is now a property in props
}
export default function Element(props: Props) {
    const elmStyles     = styles.useStyles();

    // themes:
    const variTheme     = useVariantTheme(props);
    const variSize      = useVariantSize(props);
    const variGradient  = useVariantGradient(props);



    const Tag       = (props.tag ?? 'div');
    return (
        <Tag {...props.htmlProps} // you can now pass the desired props to tag
            className={[
                elmStyles.main,
                
                // themes:
                variTheme.class,
                variSize.class,
                variGradient.class,

                ...(props.classes ?? []),
            ].filter((c) => !!c).join(' ')}
        >
            {(props as React.PropsWithChildren<Props>)?.children}
        </Tag>
    );
};

But @spender's suggestion is a better approach.但@spender 的建议是更好的方法。

Don't forget to update your hooks to accommodate this change.不要忘记更新你的钩子以适应这种变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM