Is it possible to override the type of JSX.Element in TypeScript?

Viewed 28

I want to be able to use the JSX syntax to build up a heterogenous tree-like data structure that is not a webpage or an HTML template - think goal trees, discrimination nets, ASTs, and other hierarchical structures. What I have so far works, but it has a bunch of ugly typecasts due to the fact that JSX.Element resists being overridden.

Here's a snippet showing what I mean:

/** @jsx createNode */

// Redefine the type of `Element`.
declare namespace JSX {
  type Element = { foo: boolean };
}

// The JSX factory function
export function createNode<Props extends { [key: string]: any } = {}>(
  tag: (props: Props) => JSX.Element,
  props: Props | null,
  ...children: JSX.Element[]
): JSX.Element {
  return tag(props as Props);
}

// An example component which conforms to the new JSX.Element shape.
function Test(): JSX.Element {
  return {
    foo: false,
  };
}

// An example component which conforms to React's protocol.
function Test2() {
  return {
    type: '',
    props: null,
    key: null,
  };
}

// Error: missing properties for type, props, key.
const elt = <Test />;

// Works
const elt2 = <Test2 />;

There's no React/Preact/Solid in this code, it's just pure JSX using the jsx pragma. But no matter what I try, it seems to use React's definition for the JSX type.

0 Answers
Related