typescript-compiler-api

How to query HTMLElementTagNameMap


I've got a ts.Program and string like 'my-component'. Some of the source files have declarations like declare global { interface HTMLElementTagNameMap { 'my-component': MyComponent } }. Starting with just the string 'my-component', is there a way to query the program's type checker directly to get the type for MyComponent? Or do I need to visit nodes in each source file and make my own map?

The project webcomponent-analyzer does it the second way (https://github.com/runem/web-component-analyzer/blob/1a71064c66a38923aab783e3885feefccfd19589/src/analyze/flavors/custom-element/discover-definitions.ts#L75):

if (ts.isInterfaceDeclaration(node) && ["HTMLElementTagNameMap", "ElementTagNameMap"].includes(node.name.text)) {
    const extensions = getInterfaceKeys(node, { ts, checker });
    return extensions.map(({ key, keyNode, identifier, declaration }) => ({
        tagName: key,
        tagNameNode: keyNode,
        identifierNode: identifier,
        declarationNode: declaration
    }));
}

Solution

  • Or do I need to visit nodes in each source file and make my own map?

    Yes, you will need to visit each source file (program.getSourceFiles() and filter for the relevant files), then traverse all the nodes finding 'my-component' properties.

    At the current moment and from my understanding, there's barely any way to query the type checker to resolve information without first working from the nodes.