在Typescript中使用自定义JSX编译指示的DOM元素动态道具

问题描述

使用自定义JSX编译指示时是否可以扩展DOM元素属性

类似于情感和样式组件如何使用css道具并在其jsx编译指示内管理逻辑。我想做同样的事情,但是具有可以通过通用类型配置的属性

例如,

// @jsx jsx

import { jsx } from 'my-lib';

...

<button<{ primary: boolean }> css={styles} primary={primary}>
  Hello world
</button>

我当前的类型定义看起来像这样:

interface CustomAttributes {
    css?: Cssproperties;
}


declare module 'react' {
    interface DOMAttributes extends CustomAttributes {}
}

declare global {
    namespace JSX {
        interface IntrinsicAttributes extends CustomAttributes {}
    }
}

我的幼稚解决方案看起来像这样:

interface CustomAttributes {
    css?: Cssproperties;
}


declare module 'react' {
    interface DOMAttributes<DynamicProps> extends CustomAttributes,DynamicProps {}
}

declare global {
    namespace JSX {
        interface IntrinsicAttributes<DynamicProps> extends CustomAttributes,DynamicProps {}
    }
}

相关问题: Styled components's 'css' prop with TypeScript

解决方法

您绝对可以添加一组固定的属性,但是我不知道如何使其动态。这很好用,并向所有JSX元素添加了一个可选的boolean属性'primary'。

interface CustomAttributes {
    primary?: boolean;
}

declare global {
    namespace JSX {
        interface IntrinsicAttributes extends React.Attributes,CustomAttributes {}
    }
}

当我们尝试使其通用时,会遇到麻烦,因为原始接口不是通用的。添加通用<T>会导致此错误:

TS2428:所有“ IntrinsicAttributes”声明必须具有相同的类型参数。

继承链中有一堆接口可以用来确定道具(React.DetailedHTMLProps),因此可以在其他地方添加道具。

interface DOMAttributes<T>interface HTMLAttributes<T>等。泛型,但是泛型类型T是指元素的类型(即{{1} }),而不是元素的通用参数。可以向所有button元素中添加某些道具。

我无法逾越的砖墙是如何使button元素本身变得通用,就像您的示例中button不是通用的那样。我没有足够的信心说这绝对不可能,但是我做不到。