refactor(superdoc): close strict-null cluster in SuperDoc.js (SD-2867)#3084
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
|
🎉 This PR is included in superdoc-sdk v1.8.0-next.37 |
|
🎉 This PR is included in @superdoc-dev/mcp v0.3.0-next.34 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.2.0-next.76 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.3.0-next.78 |
|
🎉 This PR is included in superdoc v1.30.0-next.35 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-cli v0.8.0-next.52 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-cli v0.9.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.32.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/mcp v0.4.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.3.0 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.4.0 |
|
🎉 This PR is included in superdoc-sdk v1.9.0 |
SD-2867 strict-null cluster, grouped PR. Closes all 40 TS2532 / TS18048 / TS2533 errors in
packages/superdoc/src/core/SuperDoc.jsusing one consistent set of patterns. No more per-error stacking.Three mechanisms cover the cluster:
Class field declarations for store-state fields that
#initVueApppopulates synchronously inside#init(superdocStore,commentsStore,highContrastModeStore,app,pinia,readyEditors,pendingCollaborationSaves). Declared without initializers because the constructed instances aren't available at field-init time; this matches the existing pattern forusers/version/whiteboard. Closes ~25 sites where TS thought the field could be undefined because the assignment lived in a separate method.InternalConfigcast at sites that readthis.config.documents,this.config.modules, orthis.config.layoutEngineOptionsafter#inithas normalized them.InternalConfig(incore/types/index.ts) gains four required-field overrides (documents,modules,user,layoutEngineOptions) representing the runtime invariants#initalways produces. PublicConfigis unchanged; only the internal augmentation type tightens. Closes ~13 sites.Make the runtime invariants real:
#initnow explicitly normalizesthis.config.documents = this.config.documents || []andthis.config.layoutEngineOptions = this.config.layoutEngineOptions || {}afternormalizeTrackChangesConfig. Themodules || {}anduserdefaults already existed; this completes the set so everyInternalConfigcast site has the value it claims. Note:normalizeTrackChangesConfigalready populateslayoutEngineOptionsinternally, so the explicit guard here is belt-and-suspenders rather than a fresh fix - it makes the invariant legible at the#initboundary instead of relying on a side effect of an unrelated helper.Public surface is unchanged. The
SuperDoc.d.tsemits the sameconfig: Configfield; the new class fields emit with their preciseReturnType<typeof useStoreFn>types (noanyleaks).InternalConfigis not re-exported through the package entry, so consumers don't see the tightening.Total errors in
SuperDoc.js(under probed// @ts-check) drop from ~130 to ~102. Remaining categories (TS2339 cascade, TS2345, TS2322) land in subsequent SD-2867 grouped PRs per the updated ticket plan.Verified:
pnpm --filter superdoc check:jsdoc→ 3 gated files cleanpnpm --filter superdoc build:es→ no FAIL-level findingspnpm --filter superdoc audit:declarations→ no FAIL-level findingsnode tests/consumer-typecheck/typecheck-matrix.mjs→ 33 passed, 0 failedMust stay the same:
Configshape (no required fields added)superdoc.config(still typed asConfig)superdoc.superdocStore/commentsStore(still emit Pinia store types; SD-2915 tracks the deepanycleanup separately)Review: confirm
InternalConfigchanges don't leak into public.d.ts(they shouldn't since the type isn't re-exported); confirm the#initnormalization changes aren't observable to consumers (no behavior change for configs that already pass these fields, and thedocuments: []default already existed via the class-field initializer for the no-source case).