Skip to content

Slow Performance with Type Inference on JSX Element #43717

Closed as not planned
Closed as not planned
@scottwillmoore

Description

@scottwillmoore

Version
TypeScript 4.2.4
TypeScript 4.3.0-dev.20210417

Expected Behaviour
Any changes made to the Box component have fast validation and auto-completion for associated attributes.

Actual Behaviour
TypeScript validation and auto-completion is slow.

Description
I have been investigating the current trend to create a generic React element which will pass through an element property and associated attributes and call React.createElement. An approach similar to this is used by several prominent projects such as Material UI and Github Primer. I wanted to ensure that TypeScript will infer the correct attributes from the given element property. The code I wrote does work, however it does appear to have a significant performance impact.

Related
This issue may be related to these issues: #34801, #43485, #42010, #14729, #38583.

Example
A small, reproducible example can be found at: https://github.com/scottwillmoore/react-box. You can also experiment with it in CodeSandbox. The CodeSandbox version has some differences.

The meat of the TypeScript can be seen below:

import React from "react";

type ElementType = keyof JSX.IntrinsicElements;

type ElementProperties<T extends ElementType> = JSX.IntrinsicElements[T];

type WithElement<T extends ElementType> = {
    element: T;
} & ElementProperties<T>;

type WithChildren = {
    children?: React.ReactNode;
};

type BoxProperties<T extends ElementType> = WithElement<T> & WithChildren;

function Box<T extends ElementType>({ element, children, ...properties }: BoxProperties<T>) {
    return React.createElement(element, properties, children);
}

export default function App() {
    return (
        <Box element="a" href="#">
            Hello, world!
        </Box>
    );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions