Eliminate 21 of 22 @ts-expect-error suppressions and enforce strict type validation#204
Merged
Merged
Conversation
…ate 3 @ts-expect-error suppressions Co-authored-by: TobyHFerguson <6525189+TobyHFerguson@users.noreply.github.com>
…efinitions and enhance validate-types to fail on warnings Co-authored-by: TobyHFerguson <6525189+TobyHFerguson@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Convert legacy namespace modules to class pattern
Eliminate 21 of 22 @ts-expect-error suppressions and enforce strict type validation
Jan 21, 2026
… any types ## Summary This commit eliminates the remaining type safety issues by: 1. Replacing all InstanceType<typeof X> JSDoc typedefs with proper imports from Externals.d.ts 2. Adding detection guidance for hidden any types that resolve silently 3. Fixing type errors exposed by better type resolution ## Changes Made ### Type Definition Patterns (Critical Fix) - **Root cause**: @typedef {InstanceType<typeof X>} in .js files cannot resolve GAS globals, silently defaulting to any type - **Solution**: Use @typedef {import('./Externals').XInstance} pattern which imports from .d.ts where TypeScript's module resolution works ### Files Modified #### Externals.d.ts (New Instance Types) - Added SCCCCEventInstance export - Added ScheduleAdapterInstance export - Now canonical location for all instance type definitions #### Type Definition Updates - RideManager.js: Fixed RowCoreInstance typedef - AnnouncementManager.js: Added RowCoreInstance import, fixed all usages - EventFactory.js: Added RowCoreInstance and SCCCCEventInstance imports - MenuFunctions.js: Added RowCoreInstance and ScheduleAdapterInstance imports - ScheduleAdapter.js: Changed to import RowCoreInstance - ScheduleAdapter.example.js: Added RowCoreInstance import - triggers.js: Added ScheduleAdapterInstance import - UIHelper.js: Changed to import RowCoreInstance - ValidationCore.js: Changed to import RowCoreInstance #### Type Safety Fixes - AnnouncementManager.js: Fixed _rowNum undefined coercion (row.rowNum ?? 0) - AnnouncementManager.js: Fixed announcementCell access for new {text, url} object structure #### Documentation - .github/copilot-instructions.md: Added new section "Detecting Hidden any Types (CRITICAL)" with detection methods, banned patterns, and verification procedures - .github/ISSUE_TEMPLATE.md: Updated typedef examples to use correct import pattern #### Type Definition Files (Minor Updates) - src/gas-globals.d.ts: Imported SCCCCEventInstance, ScheduleAdapterInstance - Multiple .d.ts files: Updated for consistency with new patterns ### Pattern Established (For Future Code) **BANNED Pattern** (resolves to any in .js files): @typedef {InstanceType<typeof RowCore>} RowCoreInstance **REQUIRED Pattern** (proper type resolution): @typedef {import('./Externals').RowCoreInstance} RowCoreInstance ### Why This Matters - Fixes type resolution issues where types appeared as 'any' when hovering in VS Code - Enables compile-time type checking instead of silent runtime failures - Prevents entire classes of bugs where typos and missing properties went undetected - Reduces confusion between different resolution strategies in .d.ts vs .js files ### Testing & Verification - All 725 tests still pass - npm run typecheck: 0 errors - get_errors(): No errors found - Type resolution: All instance types now show actual properties, not 'any' ## Related Issues - Fixes hidden 'any' type discovery mentioned in recent development - Part of PR #204: "Eliminate 21 of 22 @ts-expect-error suppressions" ## Notes for Future Maintainers 1. Always create/import instance types from Externals.d.ts 2. Never use InstanceType<typeof X> in .js files with JSDoc 3. Hover over typedef names to verify they don't show "= any" 4. Use grep -rn "InstanceType<typeof" src/*.js to find regressions 5. See .github/copilot-instructions.md "Detecting Hidden any Types" section
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Production TypeError reached prod because @ts-expect-error suppressed all errors on affected lines, not just intended ones. Baseline: 22 suppressions masking type coverage gaps.
Changes
Eliminated 21 suppressions (95% reduction):
nullinference onupdatesobjectgas-globals.d.tsParagraph,ListItem,Table,TableRow,TableCell,Bodyinterfaces/** @type {GoogleAppsScript.Document.ListItem} */ const listItem = /** @type {any} */ (element);Fixed class pattern violations:
this.buildValidationMessage→UIHelper.buildValidationMessage(3 instances)Enhanced validate-types script:
_-prefixed private methods)Type Safety Impact
Before:
After:
Remaining suppression (1): MenuFunctions.js line 122 - architectural type mismatch (
RowvsAnnouncementQueueItem) requiring refactor beyond scope.Validation
Closes #200, #196
Original prompt
This section details on the original issue you should resolve
<issue_title>Type Safety Enforcement: Namespace to Class Conversion</issue_title>
<issue_description>## Summary
Convert all legacy namespace pattern modules to class pattern with static methods, eliminate unjustified @ts-expect-error suppressions, and enhance the validate-types script to fail on type mismatches. This is a mechanical refactoring with no behavior changes.
Combines: Issue #200 + Issue #196
Why This Matters
Each @ts-expect-error suppresses ALL errors on that line, not just the intended error. A production bug (TypeError: Cannot read properties of undefined) reached production because type checking was disabled by these suppressions. Converting to class pattern restores full TypeScript coverage.
Current State (Baseline)
PHASE 1: Convert Namespace Modules to Class Pattern
Goal: Convert all namespace pattern modules to class pattern with static methods.
Modules to Convert (in dependency order - convert leaf modules first):
CRITICAL Conversion Rules:
Per-Module Checklist (repeat for each):
PHASE 2: Eliminate @ts-expect-error Suppressions
After Phase 1, investigate remaining suppressions:
For each suppression:
PHASE 3: Enhance validate-types Script
Current Problem: npm run validate-types shows warnings but does not fail the build.
Required Changes to scripts/validate-type-definitions.js:
VERIFICATION CHECKPOINTS
After EACH module conversion:
After Phase 1 complete:
After Phase 2 complete:
After Phase 3 complete:
SUCCESS CRITERIA
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.