Repository: solidjs/solid
File: packages/solid/web/src/index.ts (TypeScript)

Code before:
    createRoot(dispose => insert(mount, () => (!clean() ? renderPortal()() : dispose()), null));
    onCleanup(() => {
      if (sharedConfig.context) queueMicrotask(cleanup);
      else cleanup();
    });
  } else {
    const container = createElement(props.isSVG ? "g" : "div", props.isSVG),
      renderRoot =
        useShadow && container.attachShadow ? container.attachShadow({ mode: "open" }) : container;

    Object.defineProperty(container, "host", {
      get() {
        return marker.parentNode;
      }
    });
    insert(renderRoot, renderPortal());
    mount.appendChild(container);
    (props as any).ref && (props as any).ref(container);
    onCleanup(() => mount.removeChild(container));
  }
  return marker;
}

type ValidElements = keyof JSX.IntrinsicElements;
type ValidComponent<P> = (props: P) => JSX.Element;
type ValidConstructor = ValidElements | ValidComponent<unknown> | string;

type DynamicBaseProps<T extends ValidConstructor> =
  T extends ValidElements
    ? JSX.IntrinsicElements[T]
    :
  T extends ValidComponent<infer U>
    ? U
    : never;

type DynamicProps<T extends ValidConstructor> = DynamicBaseProps<T> & {
  component?: T;
};
/**
 * renders an arbitrary custom or native component and passes the other props
 * ```typescript
 * <Dynamic component={multiline() ? 'textarea' : 'input'} value={value()} />
 * ```
 * @description https://www.solidjs.com/docs/latest/api#%3Cdynamic%3E
 */
export function Dynamic<T extends ValidConstructor>(props: DynamicProps<T>): Accessor<JSX.Element> {
  const [p, others] = splitProps(props, ["component"]);
  const cached = createMemo(() => p.component)
  return createMemo(() => {
    const component = cached() as Function | string;
    switch (typeof component) {

Review comment (suggestion):
I imagine `string` would need to be `string & {}` in order for autocomplete to suggest `ValidElements`. https://tsplay.dev/WY4Mdm (works for `a` but not for `b` where it suggests all tokens).
```suggestion
type ValidConstructor = ValidElements | ValidComponent<unknown> | (string & {});
```

Code after:
    const cleanup = () => setClean(true);
    createRoot(dispose => insert(mount, () => (!clean() ? renderPortal()() : dispose()), null));
    onCleanup(() => {
      if (sharedConfig.context) queueMicrotask(cleanup);
      else cleanup();
    });
  } else {
    const container = createElement(props.isSVG ? "g" : "div", props.isSVG),
      renderRoot =
        useShadow && container.attachShadow ? container.attachShadow({ mode: "open" }) : container;

    Object.defineProperty(container, "host", {
      get() {
        return marker.parentNode;
      }
    });
    insert(renderRoot, renderPortal());
    mount.appendChild(container);
    (props as any).ref && (props as any).ref(container);
    onCleanup(() => mount.removeChild(container));
  }
  return marker;
}

type DynamicProps<T extends ValidComponent> = ComponentProps<T> & {
  component: T | undefined;
};
/**
 * renders an arbitrary custom or native component and passes the other props
 * ```typescript
 * <Dynamic component={multiline() ? 'textarea' : 'input'} value={value()} />
 * ```
 * @description https://www.solidjs.com/docs/latest/api#%3Cdynamic%3E
 */
export function Dynamic<T extends ValidComponent>(props: DynamicProps<T>): Accessor<JSX.Element> {
  const [p, others] = splitProps(props, ["component"]);
  const cached = createMemo(() => p.component)
  return createMemo(() => {
    const component = cached() as Function | string;
    switch (typeof component) {
      case "function":
        if ("_DX_DEV_") Object.assign(component, { [$DEVCOMP]: true });
        return untrack(() => component(others));

      case "string":
        const isSvg = SVGElements.has(component);
        const el = sharedConfig.context ? getNextElement() : createElement(component, isSvg);
        spread(el, others, isSvg);
        return el;

      default: