I’m experimenting with using Polaris Web Components in a Solid app. The components themselves seem to work well, but I’m having issues with the TypeScript types in @shopify/polaris-types. The main issue is with children, as the module seems to implement types for Preact and React JSX.IntrinsicElement, but the declare global types are just the React versions which are incompatible with Solid. The Preact types do appear to work (I think this is because Preact’s ComponentChild includes object, so more of a coincidence than anything). So (from my minimal testing) I can get it to work either by merging the Preact types into Solid’s JSX namespace or by patching children for Solid specifically. I’ve been using the latter approach:
import { type JSX } from 'solid-js';
import '@shopify/app-bridge-types';
import '@shopify/polaris-types';
type IntrinsicElements = globalThis.JSX.IntrinsicElements;
type ShopifyIntrinsicElements = {
[K in keyof IntrinsicElements as K extends `s-${string}` ? K : never]:
IntrinsicElements[K] extends { children?: unknown }
? Omit<IntrinsicElements[K], 'children'> & {
children?: JSX.Element;
}
: IntrinsicElements[K]
};
declare module 'solid-js' {
namespace JSX {
interface IntrinsicElements extends ShopifyIntrinsicElements {}
}
}
This seems to work pretty well but I haven’t used it enough to be sure that it doesn’t break anything.
Polaris Web Components are being sold as allowing the use of any framework, but the types don’t quite align with this ideal right now. You could add types specifically for declare module 'solid-js', but I’m not sure if that’s the right approach either. @shopify/app-bridge-types seems to specify most elements’ children as any, which probably isn’t ideal either but at least it doesn’t make any assumptions about the flavour of JSX you’re using.
@shopify/app-bridge-types also imports preact, react, and depends on @types/react, but these are all in devDependencies which means that they aren’t installed automatically when you add @shopify/polaris-types to an app. So I’ve had to add those three packages to my own devDependencies despite my app using none of them directly. I’m not an expert on TypeScript packages, but it looks like TypeScript’s own documentation suggests that libraries should put type dependencies in dependencies instead:
It makes perfect sense to me. If it’s directly importing something in the compiled artifact then it depends on that to function, in which case it’s not a development dependency.
I’ve also seen using peerDependencies suggested. I could imagine this being split up into separate imports like @shopify/polaris-types/preact, @shopify/polaris-types/react, and @shopify/polaris-types/generic and using peerDepenciesMeta to make these dependencies optional:
@shopify/app-bridge-types does not require any of these dependencies.
Another issue is that @shopify/app-bridge-types and @shopify/polaris-types both define an <s-page> component, and tsc complains about this conflict. It doesn’t break anything, but I do find it confusing and unclear why they both exist.