Skip to content

Replace double cast in factory.ts with runtime type guard #130

@Sam-Bolling

Description

@Sam-Bolling

Task

Replace the as unknown as OgcApiCollectionInfo double cast in factory.ts:57 with a runtime type guard function that validates the collection document structure before returning it as a typed CSAPI model object.

Finding Reference: F-NEW-02 from final-project-code-review.md
Severity: Minor (DESIGN)
Category: Type error
Implementation Branch: phase-6


Problem Statement

factory.ts line 57 contains a double cast:

collectionDoc as unknown as OgcApiCollectionInfo

The upstream getCollectionDocument() returns Promise<OgcApiDocument>, but the CSAPI factory needs OgcApiCollectionInfo. These types are structurally compatible (collection documents are a superset of the generic OGC API document shape), but TypeScript can't verify the compatibility without a cast.

The as unknown as X pattern bypasses the type system entirely. If the upstream return type ever changes, the compiler won't catch the mismatch — the code will silently produce a wrong type at runtime.

Evidence:

// factory.ts line 57 (current):
return new CSAPIQueryBuilder(
  collectionDoc as unknown as OgcApiCollectionInfo,
  resourceUrls
);

Impact: No functional impact today. But the double cast is a type-safety hole — if the upstream getCollectionDocument return shape ever changes, this wouldn't be caught at compile time. A type guard would catch it at runtime.

Files to Create or Modify

File Action Est. Lines Purpose
src/ogc-api/csapi/factory.ts Modify ~15 changed Add type guard function, replace double cast

Proposed Fix

Add a type guard function in factory.ts that validates the essential properties of a collection document before treating it as OgcApiCollectionInfo:

function isCollectionInfo(doc: unknown): doc is OgcApiCollectionInfo {
  return (
    typeof doc === 'object' &&
    doc !== null &&
    'id' in doc &&
    typeof (doc as Record<string, unknown>).id === 'string'
  );
}

Then replace the double cast:

// Before:
collectionDoc as unknown as OgcApiCollectionInfo

// After:
if (!isCollectionInfo(collectionDoc)) {
  throw new EndpointError(
    `Collection '${collectionId}' document is not a valid OgcApiCollectionInfo`
  );
}
// collectionDoc is now narrowed to OgcApiCollectionInfo

Scope — What NOT to Touch

  • ❌ Do NOT modify endpoint.ts — the return type of getCollectionDocument is upstream-owned
  • ❌ Do NOT modify model.ts — the OgcApiCollectionInfo interface is upstream-owned
  • ❌ Do NOT modify index.ts (barrel file)
  • ❌ Do NOT modify any test files in this issue — factory test expansion is tracked separately (Issue Expand endpoint.spec.ts CSAPI section from 3 to ~6 test cases #133)
  • ❌ Do NOT modify any other files outside factory.ts
  • ❌ Do NOT change any CSAPI business logic

Acceptance Criteria

  • Double cast as unknown as OgcApiCollectionInfo removed from factory.ts
  • Type guard function added that validates the collection document structure
  • EndpointError thrown if the document doesn't match expected shape
  • npx tsc --noEmit passes (typecheck clean)
  • npm run lint passes
  • npm run test:node passes
  • npx prettier --check src/ogc-api/csapi/factory.ts passes

Dependencies

Blocked by: Issue #129 (F-NEW-01 — remove as any cast first, since both touch the same code area)
Blocks: Nothing


Operational Constraints

⚠️ MANDATORY: Before starting work on this issue, review docs/governance/AI_OPERATIONAL_CONSTRAINTS.md and the P6 Implementation Guide.

Key constraints:

  • Precedence: OGC specifications → AI Collaboration Agreement → This issue description → Existing code → Conversational context
  • No scope expansion: Fix the finding, nothing more
  • Minimal diffs: Prefer the smallest change that satisfies the acceptance criteria
  • Zero business logic changes: Phase 6 touches the integration boundary only

References

# Document What It Provides
1 final-project-code-review.md §9 F-NEW-02 Evidence and context
2 findings-effort-assessment.md Effort estimate (1 pass, same as F-NEW-01)
3 src/ogc-api/csapi/factory.ts line 57 Code to modify
4 src/ogc-api/model.ts OgcApiCollectionInfo interface definition

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingphase-6

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions