请注意,这不是反应问题。
我很乐意实现自己的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命名空间魔术?