有没有办法让TypeScript推断出JSX.Element的实例?

时间:2017-05-12 21:03:37

标签: typescript jsx

请注意,这不是反应问题。

我很乐意实现自己的jsx工厂,并说服TypeScript来检查我的属性:

declare global {
    namespace JSX {
        interface ElementAttributesProperty {
            opts;
        }
    }
}

现在,我的工具包使用了一个非常简单的组件类型:

export abstract class Component<T, U extends HTMLElement> {
    opts: T;
    constructor(opts: T) { };
    elem: U;
}

我甚至可以走得更远,我的jsxFactory方法(名为h)可以输入如下:

export interface ComponentConstructor<T, U extends HTMLElement, K extends Component<T, U>> {
    new(props: T): K
}

function h<T,U extends HTMLElement, K extends Component<T,U>>(tag: ComponentConstructor<T,U,K>, props: T, ...children: any[]): K;
function h<K extends keyof HTMLElementTagNameMap>(tag: K, props: any, ...children: any[]): HTMLElementTagNameMap[K];

因此,这允许我正确地将h(Button, { label: "foo"})的返回类型推断为Button

但是,TypeScript的jsx推断始终返回&#34; JSX.Element&#34;,根据文档:

  

默认情况下,JSX表达式的结果输入为any。您可以   通过指定JSX.Element接口来自定义类型。然而,   无法检索有关元素的类型信息,   来自此接口的JSX的属性或子代。这是一个黑色   框。

这对我来说是&#34;任何jsx表达式总会返回完全类型JSX.Element&#34;,但如果是这样,请参阅我的信息请求这个问题的结尾。

所以在我的例子中:

let btn = <Button label="foo"/> // types as JSX.Element = any :(

鉴于h类型声明的理想行为,这感觉不尽如人意 - 是否有办法让TypeScript尊重与h相同的行为? (即推断上面的btn属于Button类型。)如果不是,为什么不可能?特别是为什么TypeScript不使用我的jsxFactory方法的定义而不是强迫我首先使用这个JSX命名空间魔术?

0 个答案:

没有答案