From 9eb4e33fac4bdc5269d29ea10002f8d3dc52d3a9 Mon Sep 17 00:00:00 2001 From: ShaneK Date: Thu, 6 Aug 2026 06:48:40 -0700 Subject: [PATCH 1/3] chore(build): add typecheck step to react and react-router --- .github/workflows/actions/build-angular-server/action.yml | 3 +++ .github/workflows/actions/build-angular/action.yml | 3 +++ .github/workflows/actions/build-react-router/action.yml | 6 ++++++ .github/workflows/actions/build-react/action.yml | 6 ++++++ docs/CONTRIBUTING.md | 2 +- docs/react-router/testing.md | 4 ++++ docs/react/testing.md | 4 ++++ docs/vue-router/testing.md | 2 +- docs/vue/testing.md | 4 ++++ packages/react-router/package.json | 1 + packages/react/package.json | 1 + 11 files changed, 34 insertions(+), 2 deletions(-) diff --git a/.github/workflows/actions/build-angular-server/action.yml b/.github/workflows/actions/build-angular-server/action.yml index 68c7054facf..70c65316883 100644 --- a/.github/workflows/actions/build-angular-server/action.yml +++ b/.github/workflows/actions/build-angular-server/action.yml @@ -23,6 +23,9 @@ runs: run: npm run lint shell: bash working-directory: ./packages/angular-server + # No Typecheck step here. Unlike the rollup-built packages, which report + # type errors as warnings and still exit 0, ng-packagr fails the build on + # them, so the Build step below already covers this. - name: 🏗️ Build run: npm run build.prod shell: bash diff --git a/.github/workflows/actions/build-angular/action.yml b/.github/workflows/actions/build-angular/action.yml index 12e1db1f5dc..bc4b1ff1ba3 100644 --- a/.github/workflows/actions/build-angular/action.yml +++ b/.github/workflows/actions/build-angular/action.yml @@ -23,6 +23,9 @@ runs: run: npm run lint shell: bash working-directory: ./packages/angular + # No Typecheck step here. Unlike the rollup-built packages, which report + # type errors as warnings and still exit 0, ng-packagr fails the build on + # them, so the Build step below already covers this. - name: 🏗️ Build run: npm run build shell: bash diff --git a/.github/workflows/actions/build-react-router/action.yml b/.github/workflows/actions/build-react-router/action.yml index e89c67abe60..bb2cbb27eea 100644 --- a/.github/workflows/actions/build-react-router/action.yml +++ b/.github/workflows/actions/build-react-router/action.yml @@ -28,6 +28,12 @@ runs: run: npm run lint shell: bash working-directory: ./packages/react-router + # The rollup build reports type errors as warnings and still succeeds, so + # this step is what keeps the package type-clean. + - name: 🔎 Typecheck + run: npm run typecheck + shell: bash + working-directory: ./packages/react-router - name: 🏗️ Build run: npm run build shell: bash diff --git a/.github/workflows/actions/build-react/action.yml b/.github/workflows/actions/build-react/action.yml index 8069483deb1..b7d3ac6b99a 100644 --- a/.github/workflows/actions/build-react/action.yml +++ b/.github/workflows/actions/build-react/action.yml @@ -23,6 +23,12 @@ runs: run: npm run lint shell: bash working-directory: ./packages/react + # The rollup build reports type errors as warnings and still succeeds, so + # this step is what keeps the package type-clean. + - name: 🔎 Typecheck + run: npm run typecheck + shell: bash + working-directory: ./packages/react - name: 🏗️ Build run: npm run build shell: bash diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index b82186ad0b1..d55e58da4a5 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -323,7 +323,7 @@ Refer to [Ionic's E2E testing guide](/core/src/utils/test/playwright/docs/README - Vue: [`/packages/vue/src`](/packages/vue/src) 2. Make your changes to the files. If the change is overly complex or out of the ordinary, add comments so we can understand the changes. 3. Run lint on the directory and make sure there are no errors. -4. For Vue, run `npm run typecheck` in `/packages/vue` and `/packages/vue-router`. The rollup build only reports type errors as warnings, so a passing build does not mean the types are clean. +4. For React and Vue, run `npm run typecheck` in each package you changed (`/packages/react`, `/packages/react-router`, `/packages/vue`, `/packages/vue-router`). These packages build with rollup, which only reports type errors as warnings, so a passing build does not mean the types are clean. Angular has no `typecheck` script because ng-packagr already fails the build on type errors. 5. Build the project. 6. After the build is finished, commit the changes. Please follow the [commit message format](#commit-message-format) for every commit. 7. [Submit a Pull Request](#submit-pull-request) of your changes. diff --git a/docs/react-router/testing.md b/docs/react-router/testing.md index 68b8c6236ce..ce7b6190c36 100644 --- a/docs/react-router/testing.md +++ b/docs/react-router/testing.md @@ -2,6 +2,10 @@ Ionic Framework supports multiple versions of React Router. As a result, we need to verify that Ionic works correctly with each of these React Router versions. +## Type Checking + +Run `npm run typecheck` in `packages/react-router` to check types. The rollup build only reports type errors as warnings, so a passing build does not mean the types are clean. + ## Syncing Local Changes The React test app supports syncing your locally built changes for validation. diff --git a/docs/react/testing.md b/docs/react/testing.md index 1c9da9c6829..8c7fc56549c 100644 --- a/docs/react/testing.md +++ b/docs/react/testing.md @@ -2,6 +2,10 @@ Ionic Framework supports multiple versions of React. As a result, we need to verify that Ionic works correctly with each of these React versions. +## Type Checking + +Run `npm run typecheck` in `packages/react` to check types. The rollup build only reports type errors as warnings, so a passing build does not mean the types are clean. + ## Syncing Local Changes The React test app supports syncing your locally built changes for validation. diff --git a/docs/vue-router/testing.md b/docs/vue-router/testing.md index 47cacef4d1d..a6a514a2b21 100644 --- a/docs/vue-router/testing.md +++ b/docs/vue-router/testing.md @@ -2,6 +2,6 @@ ## Tests -* This package has no unit tests of its own. Its behavior is covered by the `@ionic/vue` test app, in `packages/vue/test/base/tests`. See [Vue Testing](../vue/testing.md). +* This package has no unit tests of its own. Its behavior is covered by the `@ionic/vue` test app, in `packages/vue/test/base/tests`. Refer to [Vue Testing](../vue/testing.md). * Run `npm run typecheck` to check types. The rollup build only reports type errors as warnings. * Bug fix and feature PRs should have new tests verifying the PR functionality. diff --git a/docs/vue/testing.md b/docs/vue/testing.md index a7f37b9754c..bf27446bee7 100644 --- a/docs/vue/testing.md +++ b/docs/vue/testing.md @@ -2,6 +2,10 @@ Ionic Framework supports multiple versions of Vue. As a result, we need to verify that Ionic works correctly with each of these Vue versions. +## Type Checking + +Run `npm run typecheck` in `packages/vue` to check types. The rollup build only reports type errors as warnings, so a passing build does not mean the types are clean. + ## Syncing Local Changes The Vue test app supports syncing your locally built changes for validation. diff --git a/packages/react-router/package.json b/packages/react-router/package.json index cf362013ee0..b0b17d13bc1 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -28,6 +28,7 @@ "prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx}\"", "lint": "npm run eslint && npm run prettier -- --write --cache", "lint.fix": "npm run eslint -- --fix && npm run prettier -- --write --cache", + "typecheck": "tsc --noEmit", "sync": "sh ./scripts/sync.sh" }, "main": "dist/index.js", diff --git a/packages/react/package.json b/packages/react/package.json index 7a6f0eb9852..729a6ce3b0a 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -28,6 +28,7 @@ "prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx}\"", "lint": "npm run eslint && npm run prettier -- --write --cache", "lint.fix": "npm run eslint -- --fix && npm run prettier -- --write --cache", + "typecheck": "tsc --noEmit", "copy": "node scripts/copy.js", "test.spec": "jest --ci", "sync": "sh ./scripts/sync.sh", From a2f9c583f6a9ab3676758fb12d206abcedfccd25 Mon Sep 17 00:00:00 2001 From: ShaneK Date: Thu, 6 Aug 2026 07:32:16 -0700 Subject: [PATCH 2/3] chore(build): enable skipLibCheck in react typecheck --- packages/react/tsconfig.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index 86e3d2b1032..759fb189c36 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -13,6 +13,13 @@ */ "rootDir": "src", "types": ["node", "jest", "@testing-library/jest-dom"], + /* + * @types/node is pinned to v14 here, which predates AbortSignal.any() in + * lib.dom.d.ts, so the two global declarations of AbortSignal conflict + * (TS2403). skipLibCheck keeps tsc from checking declaration files we do + * not own; errors in this package's own source are still reported. + */ + "skipLibCheck": true, "inlineSources": true, "sourceMap": true, "jsx": "react-jsx", From b5ad8bc23428116adf68281785866bfb1924fb0d Mon Sep 17 00:00:00 2001 From: ShaneK Date: Thu, 6 Aug 2026 07:51:22 -0700 Subject: [PATCH 3/3] chore(react): bump @types/node to v22 and drop skipLibCheck --- packages/react/package-lock.json | 21 ++++++++++++++++----- packages/react/package.json | 2 +- packages/react/tsconfig.json | 7 ------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 6afbd2be0ea..f51e75b9c74 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -24,7 +24,7 @@ "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.3.2", "@types/jest": "^26.0.15", - "@types/node": "^14.0.14", + "@types/node": "^22.9.3", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "@typescript-eslint/eslint-plugin": "^8.0.0", @@ -2140,10 +2140,14 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "14.18.63", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", - "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", - "dev": true + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@types/prop-types": { "version": "15.7.9", @@ -8938,6 +8942,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", diff --git a/packages/react/package.json b/packages/react/package.json index 729a6ce3b0a..476fc199535 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -60,7 +60,7 @@ "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.3.2", "@types/jest": "^26.0.15", - "@types/node": "^14.0.14", + "@types/node": "^22.9.3", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "@typescript-eslint/eslint-plugin": "^8.0.0", diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index 759fb189c36..86e3d2b1032 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -13,13 +13,6 @@ */ "rootDir": "src", "types": ["node", "jest", "@testing-library/jest-dom"], - /* - * @types/node is pinned to v14 here, which predates AbortSignal.any() in - * lib.dom.d.ts, so the two global declarations of AbortSignal conflict - * (TS2403). skipLibCheck keeps tsc from checking declaration files we do - * not own; errors in this package's own source are still reported. - */ - "skipLibCheck": true, "inlineSources": true, "sourceMap": true, "jsx": "react-jsx",