Esri / calcite-design-system

A monorepo containing the packages for Esri's Calcite Design System
https://developers.arcgis.com/calcite-design-system/
Other
285 stars 76 forks source link

bug: Preact typing doesn't work if using non-legacy TypeScript moduleResolution #9494

Open maxpatiiuk opened 4 months ago

maxpatiiuk commented 4 months ago

Check existing issues

Actual Behavior

Calcite provides typings for Preact. However, these work only if using legacy TypeScript moduleResolution setting "Node"

Expected Behavior

Using modern moduleResolution like "Node16" or "Bundler" should work. Without this, you can't use the package.json's "exports" field

Reproduction Sample

https://github.com/Esri/calcite-components-examples/tree/main/preact-typescript

Reproduction Steps

  1. Clone this folder: https://github.com/Esri/calcite-components-examples/tree/main/preact-typescript
  2. In tsconfig on this line, replace the legacy module resolution with a modern one:
    -     "moduleResolution": "Node",
    +     "moduleResolution": "Node16", // or "Bundler"
  3. See error anywhere where calcite elements are used in JSX

    Property 'calcite-icon' does not exist on type 'JSX.IntrinsicElements'.ts(2339)

Reproduction Version

2.8.5

Relevant Info

The issue is likely because the preact typings generated by Calcite reference a "preact/src/jsx" file which is not included in Preact's package.json's "exports" field:

https://github.com/Esri/calcite-design-system/blob/9b4c3ee086a534714cda1020bee084e19f385068/packages/calcite-components/support/preact.ts#L26

Note, because of TypeScript limitation, this might be not possible to solve without opening a PR in Preact to add this to their package.json's exports:

    "./src/jsx": { "types": "./src/jsx.d.ts" },

With the above line, Calcite's typings seem to work again

Regression?

No response

Priority impact

impact - p3 - not time sensitive

Impact

I tried to add Preact typings to arcgis-web-components, but faced an issue. When I looked at how typings work in Calcite, I noticed that Calcite's Preact typings don't work with newer TypeScript module resolution setting.

Calcite package

Esri team

ArcGIS Maps SDK for JavaScript

maxpatiiuk commented 4 months ago

As per https://github.com/preactjs/preact/issues/1180#issuecomment-643681851, changing the preact.d.ts that Calcite generates like so appears to work both with the legacy and the new moduleResolution strategy:

- import { JSXInternal } from "preact/src/jsx"; 
- import { JSX } from "./components";
+ import { JSX as JSXInternal } from "preact";
+ import { JSX as CalciteJsx } from "./components";

- declare module "preact/src/jsx" {
-   namespace JSXInternal {
+ declare module 'preact' {
+   namespace createElement.JSX extends JSXInternal.IntrinsicElements {

This seems to work because new versions of TypeScript look at the jsx factory function to resolve the JSX namespace

In addition:

@paulcpederson Since you worked on the original Calcite types for Preact, could you please verify if the above fix looks good and if so if it can be integrated into the preact.d.ts that Calcite ships?

geospatialem commented 2 weeks ago

Spike to determine if the breaking change release mitigates the above.

maxpatiiuk commented 2 weeks ago

Note, this issue will be fixed automatically upon migration to Lit, thus you could delay addressing it until then.

jcfranco commented 3 days ago

Blocked by #10310.