Skip to content

Using an intrinsic element in JSX that has only an index type in IntrinsicElements makes the compiler crash with a confusing error #42753

Closed
@IceCreamYou

Description

@IceCreamYou

Bug Report

🔎 Search Terms

Custom JSX Factory
JSX.IntrinsicElements index type
getIntrinsicAttributesTypeFromJsxOpeningLikeElement
getIndexSymbol
tsc crash

🕗 Version & Regression Information

  • This is a crash
  • This is the behavior in every version I tried (3.7.4, 4.1.5, 4.2.0-dev.20210207)
  • I reviewed the FAQ and docs for entries about custom JSX factories and this crash

⏯ Playground Link

Workbench link with relevant code

💻 Code

// @jsx: react
// @jsxFactory: X.jsx

export class X {
    static jsx() {
        return document.createElement('p');
    }
}

export namespace X {
    export namespace JSX {
        export type IntrinsicElements = {
            [other: string]: any;
        };
    }
}

function A() {
    return (<p>Hello</p>);
}

🙁 Actual behavior

Normally if one uses an intrinsic element in HTML that does not have a JSX type, one expects to get a compiler error like Property 'p' does not exist on type JSX.IntrinsicElements. However if IntrinsicElements has an index type, the compiler crashes instead. The error you get depends on the version of TypeScript you are using and whether the element is self-closing. Here is what I get in tsc 3.7.4 for a non-self-closing tag:

$ tsc
/usr/local/lib/node_modules/typescript/lib/tsc.js:78593
                throw e;
                ^

TypeError: Cannot read property 'type' of undefined
    at getIntrinsicAttributesTypeFromJsxOpeningLikeElement (/usr/local/lib/node_modules/typescript/lib/tsc.js:44731:100)
    at resolveJsxOpeningLikeElement (/usr/local/lib/node_modules/typescript/lib/tsc.js:46552:30)
    at resolveSignature (/usr/local/lib/node_modules/typescript/lib/tsc.js:46591:28)
    at getResolvedSignature (/usr/local/lib/node_modules/typescript/lib/tsc.js:46602:26)
    at checkJsxOpeningLikeElementOrOpeningFragment (/usr/local/lib/node_modules/typescript/lib/tsc.js:44785:27)
    at checkJsxElementDeferred (/usr/local/lib/node_modules/typescript/lib/tsc.js:44436:13)
    at checkDeferredNode (/usr/local/lib/node_modules/typescript/lib/tsc.js:52772:21)
    at Map.forEach (<anonymous>)
    at checkDeferredNodes (/usr/local/lib/node_modules/typescript/lib/tsc.js:52747:37)
    at checkSourceFileWorker (/usr/local/lib/node_modules/typescript/lib/tsc.js:52807:17)

For a self-closing tag I instead get TypeError: Cannot read property 'members' of undefined at getIndexSymbol (/usr/local/lib/node_modules/typescript/lib/tsc.js:35041:27) ...

🙂 Expected behavior

Considering that this is very similar to an example given in the official docs, I expected it to be supported.

At minimum it would be nice if this did not crash the compiler. I would prefer if JSX.IntrinsicElements supported index types - not everyone wants to maintain a giant list of every HTML element. But I would settle for a more understandable error. This error could either be raised as soon as the compiler sees an index type on JSX.IntrinsicElements (along the lines of JSX.IntrinsicElements does not support index types) or when an unknown element is seen (e.g. '[tagname]' not found in index type of JSX.IntrinsicElements).

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions