Skip to content

strict mode: Enable TypeScript strict mode across the core-web workspace #35932

Description

@nicobytes

Description

Enable TypeScript strict mode incrementally across the entire core-web Nx workspace, one project at a time, rather than a big-bang global strict: true.

Today core-web/tsconfig.base.json has "strict": false, and it stays that way — the rollout never flips it globally. Each project opts in via its own tsconfig.json, keeping every PR small and reviewable.

The rollout follows the project dependency graph bottom-up (leaf libraries first, applications last). When a project is activated, all of its internal dependencies are already strict, so the type errors surfaced are genuinely its own instead of leaked any from upstream.

Approach (updated)

The original plan was to use typescript-strict-plugin with an opt-in paths list. That approach was dropped. The bootstrap issue (#35933) was closed without the plugin ever landing — it is absent from package.json, pnpm-lock.yaml, and main — and the first merged rollout PR (#36879, dotcms-models) instead used per-project tsconfig.json flags. That is now the established pattern:

"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true

There is no tsc-strict script and no // @ts-strict-ignore escape hatch. Sub-issues still referencing either are stale — ignore those acceptance criteria.

What enforces strict: for Rollup libraries that emit declarations ("declaration": true), @rollup/plugin-typescript is in the build chain and reports type errors, so the existing build target is the gate — CI runs nx run-many -t build via the build-test execution in core-web/pom.xml. Angular libraries typecheck through ng-packagr. Vite-based projects are the exception: their builds use esbuild and skip type checking, which is why the Nx Vite plugin infers a separate typecheck target for them. Note that lint does not catch type errors — ESLint reports lint rules, not TS diagnostics.

See core-web/CLAUDE.md → "TypeScript Strict Mode" for the per-project procedure.

This Epic tracks one task per TS project (42 total), each its own small PR, executed in strict dependency order.

Excluded from scope: dotcms-scss (SCSS only), dotcms-ui-e2e (e2e), mcp-server, and the empty root core-web project.

Removed from the rollout — dead libraries

Two projects were dropped after investigation showed they are dead code that does not compile. Removal is tracked in #36950:

Project Issue Why
dotcms #35936 (closed) Legacy initDotCMS SDK. 0 dependents, tagged skip:build/lint/test, broken dotcms-models import, last npm publish 2022-10-10. Superseded by @dotcms/client.
dot-layout-grid #35937 (closed) Legacy NgGrid grid. 0 dependents, no build target at all, imports ComponentFactoryResolver (removed from Angular), peer deps pinned to Angular 6/7. Last consumer deleted 2024-08-22. Superseded by GridStack in libs/template-builder.

Process note: the sub-issues were generated from the Nx dependency graph without checking whether each project was still alive. An audit of all 44 confirmed the problem is bounded to these two — every other library in the rollout has real dependents — but future automated rollouts should verify liveness before generating issues.

Progress

Issue Project Outcome
#35934 dotcms-models Done — PR #36879 (established the per-project pattern)
#35935 sdk-types Already compliant before the epic; PR #36957 shipped the docs
#35936 dotcms Dead library — closed, removal tracked in #36950
#35937 dot-layout-grid Dead library — closed, removal tracked in #36950
#35938 sdk-create-app Done — PR #36957 (2 errors)
#35939 dotcms-js Done — PR #36957 (38 errors)
#35940 utils Done — PR #36957 (32 lib + 17 spec errors)
#35941 sdk-uve Already compliant before the epic — closed, no diff
#35942 sdk-client Already compliant before the epic — closed, no diff
#35943 dotcms-webcomponents Groundwork only in PR #36957 — Stencil decorator members prepared; strict still off, ~250 errors across 38 files remain
#35944 utils-testing Done — PR #36957 (flags were present but inert: a stale types: ["jasmine"] aborted all type checking)
#35945 sdk-react Done — PR #36957 (14 TS4111 accesses; build verified as a real gate by negative test)

Enforcement is uneven and worth tracking. Only some of these projects have CI that actually verifies the flags.

  • Enforced through their build: sdk-types, sdk-create-app, sdk-uve, sdk-client and sdk-react — the Nx rollup, esbuild and tsc executors all type-check.
  • Declared but unverified: dotcms-js, utils and utils-testing have no build target and are tag-excluded from lint and test, so their flags are documentation only — a regression there would not be caught. Worth a follow-up decision on whether to add typecheck targets for that class of project.
  • The opposite case: dotcms-webcomponents has no skip:build, so Stencil type-checks it on every PR. There the gate is real and strict is all-or-nothing — it cannot be switched on until the error count reaches zero.

A related trap found along the way: a tsconfig that names a types entry which is not installed makes tsc emit TS2688 and stop before semantic checking, so it reports one error no matter what the code does. That is what hid utils-testing's real errors, and it means a stable error count across a change proves nothing in that situation.

Execution order (high level)

Layer 0  dotcms-models, sdk-types, ...
Layer 1  dotcms-js, utils, sdk-uve, ...
Layer 2  utils-testing, sdk-react, ...
Layer 3  data-access, ...
Layer 4  global-store
Layer 5  ui
Layer 6  block-editor + portlets-*
Layer 7  edit-ema-ui, portlets-content-drive
Layer 8  edit-content
Layer 9  portlets-edit-ema-portlet
Layer 10 dotcms-ui (app)

The full ordered list lives in the sub-issues, numbered [NN/44] (numbering kept as originally generated; two of those numbers are now closed as not applicable).

Desired Outcome

  • All in-scope core-web projects compile clean under strict with zero errors.
  • Every strict project is actually enforced by a CI target (build or typecheck) — strict flags that nothing verifies are worthless.
  • No regressions: nx affected -t build,lint stays green throughout.
  • New any usage trends toward zero.

Target Personas

  • Developer teams
  • Content teams
  • DevOps teams
  • System administrators (dotCMS)

Links

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status
    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions