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

Enforcement is uneven and worth tracking. Only some of these projects have CI that actually verifies the flags. sdk-types, sdk-create-app and sdk-uve are enforced through their build (the Nx rollup and esbuild executors both type-check). dotcms-js and utils 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.

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