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

Code before:

    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) {
      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;

Review comment (suggestion):
This is basically [`ComponentProps`](https://github.com/solidjs/solid/blob/main/packages/solid/src/render/component.ts#L75-L80), can we use that instead? 

I guess we still need to correctly parse `string & {}` though (should it return `{ [x: string]: unknown }`? Web Components will probably end up there if not added to `JSX.IntrinsicElements`). The question is whether `ComponentProps` should be changed to accept it, or if it should be handled here. 

Code after:
        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:
        break;
    }
  });
}