Я предполагаю, что вы создаете файл определения типа dom.d.ts
для dom.js
.
Пространство имен не является правильным типом для dom
. Пространство имен TS во время выполнения JS представляется как простой объект. Но dom
является одновременно вызываемой функцией и объектом с дополнительными свойствами. Таким образом, вы должны использовать интерфейс с вызываемой подписью для представления dom
в TS.
dom.d.ts
interface EtchElement<T extends string, P = any> {
tag: T;
props: P;
children: any[];
ambiguous: any[];
}
type EtchCreateElement<T extends string, P> = (props: P, ...children: any[]) => EtchElement<T, P>;
interface EtchDOM {
<T extends string, P>(tag: T, props: P, ...children: any[]): EtchElement<T, P>;
div: EtchCreateElement<"div", any>;
// ... more tags here
}
declare const dom: EtchDOM;
export = dom;
Поддержка JSX
Теперь, если вы также намереваетесь поддерживать использование JSX, вам сначала нужно прочитать официальное руководство JSX , чтобы узнать требования. Я выделю эту выдержку:
Intrinsi c элементы ищутся в специальном интерфейсе JSX.IntrinsicElements. [...] если этот интерфейс присутствует, то имя элемента intrinsi c ищется как свойство в интерфейсе JSX.IntrinsicElements.
Соберите вместе, вот скромный тип определение, которое работает:
interface EtchElement<T extends string, P = any> {
tag: T;
props: P;
children: any[];
ambiguous: any[];
}
type EtchCreateElement<T extends string, P> = (props: P, ...children: any[]) => EtchElement<T, P>;
interface EtchDOM {
<T extends string, P>(tag: T, props: P, ...children: any[]): EtchElement<T, P>;
div: EtchCreateElement<"div", JSX.IntrinsicElements["div"]>;
// ... more tags here
}
declare const dom: EtchDOM;
export = dom;
declare global {
namespace JSX {
interface Element extends EtchElement<any, any> {}
interface IntrinsicElements {
div: any; // constraint on props of "div" element
}
}
}