> For the complete documentation index, see [llms.txt](https://docs.wellcomecollection.org/request-for-comments-rfcs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wellcomecollection.org/request-for-comments-rfcs/086-item-viewer-refactor/06-phase-0-type-audit.md).

# Phase 0: Type Audit and Cleanup

Duration: 1-2 hours\
Priority: Critical - Must complete before refactoring

## Overview

Before refactoring, audit and fix all types in the ItemViewer section to ensure type safety and catch errors early. Proper typing makes refactoring safer and easier to validate.

## Findings from Actual Codebase

### Types Are Mostly Good!

The ItemViewer section has mostly well-typed code:

* All components have explicit prop types
* Core types are well-defined in `content/webapp/types/manifest.ts` and `content/webapp/types/item-viewer.ts`
* Most functions have proper return types
* No widespread use of `any`

### Already Using Official IIIF Types

The codebase already uses the official IIIF Presentation 3.0 types:

* Package: `@iiif/presentation-3` (v2.1.3)
* Importing official types: `Manifest`, `Canvas`, `ContentResource`, `ChoiceBody`, `InternationalString`, etc.
* Source: <https://iiif.io/api/presentation/3.0/>

Custom types extend official types:

```typescript
// TransformedCanvas extends official IIIF Canvas structure
export type TransformedCanvas = {
  id: string;
  type: NonNullable<ResourceType>;  // Uses official ResourceType
  // ... adds Wellcome-specific transformations
  painting: (ChoiceBody | ContentResource)[];  // Uses official types
  metadata: MetadataItem[];  // Uses official MetadataItem
};
```

This is best practice - use official types where available, extend for custom needs.

### Issues Found

#### 1. Implicit `any` in `setSearchResults` (2 locations)

Problem:

```typescript
// content/webapp/contexts/ItemViewerContext/index.tsx
setSearchResults: (v) => void;  // 'v' is implicitly 'any'

// content/webapp/views/pages/works/work/IIIFViewer/IIIFViewer.tsx
setSearchResults: (v) => void;  // 'v' is implicitly 'any'
```

Fix:

```typescript
setSearchResults: (v: SearchResults | null) => void;  // OK
```

#### 2. Missing Type Documentation for Common Patterns

While types exist, several commonly-used patterns don't have named types:

Pattern: Image Service Object

```typescript
// Used in multiple files (ZoomedImage.tsx, IIIFViewer.tsx)
const mainImageService = { '@id': currentCanvas?.imageServiceId };
```

Recommendation: Add a named type for clarity:

```typescript
// content/webapp/types/item-viewer.ts
export type ImageService = {
  '@id': string | undefined;
};
```

#### 3. Type Centralisation

Types should live in predictable locations to avoid duplication and confusion:

Current type locations:

* IIIF-related types: `content/webapp/types/manifest.ts`
* ItemViewer-specific types: `content/webapp/types/item-viewer.ts`
* Catalogue API types: `content/webapp/services/wellcome/catalogue/types/`
* Component-specific types: Defined near components when only used locally

Principles for type centralisation:

* Shared types used across multiple features belong in `content/webapp/types/`
* API response types belong near their service in `content/webapp/services/`
* Component-specific types can stay in component files if only used there
* Don't duplicate types - import and reuse existing definitions
* When unsure, check if a type already exists before creating a new one

Check for type duplication:

* Search for similar type names before adding new types
* Look for inline type definitions that could use existing types
* Consolidate multiple definitions of the same concept

## Tasks

### 1. Fix Implicit `any` Types

Files to edit:

* `content/webapp/contexts/ItemViewerContext/index.tsx`
* `content/webapp/views/pages/works/work/IIIFViewer/IIIFViewer.tsx`

Change:

```diff
- setSearchResults: (v) => void;
+ setSearchResults: (v: SearchResults | null) => void;
```

### 2. Add Missing Type Definitions (Optional but Recommended)

File: `content/webapp/types/item-viewer.ts`

Add type for image service pattern:

```typescript
import { Canvas, Manifest } from '@iiif/presentation-3';

// Existing types (keep)
export type CanvasRotatedImage = { canvas: number; rotation: number };

export type ItemViewerQuery = {
  canvas: number;
  manifest: number;
  query: string;
  page: number;
  shouldScrollToCanvas: boolean;
};

export type ParentManifest = Pick<Manifest, 'behavior'> & {
  canvases: Pick<Canvas, 'id' | 'label'>[];
};

// NEW: Add image service type for common pattern
export type ImageService = {
  '@id': string | undefined;
};
```

This makes the pattern explicit and easier to understand when refactoring.

### 3. Document Existing Type Structure

Before refactoring, understand what types are already available:

Data Types:

* `TransformedManifest` - `content/webapp/types/manifest.ts`
* `TransformedCanvas` - `content/webapp/types/manifest.ts`
* `WorkBasic` - `content/webapp/services/wellcome/catalogue/types/work.ts`
* `Work` - `content/webapp/services/wellcome/catalogue/types/index.ts`
* `SearchResults` - `@weco/content/services/iiif/types/search/v3`
* `UiTree` - `@weco/content/views/pages/works/work/work.types`

ItemViewer Types:

* `CanvasRotatedImage` - `content/webapp/types/item-viewer.ts`
* `ItemViewerQuery` - `content/webapp/types/item-viewer.ts`
* `ParentManifest` - `content/webapp/types/item-viewer.ts`

Context Type:

* `Props` (ItemViewerContext) - `content/webapp/contexts/ItemViewerContext/index.tsx`

### 4. Verify Component Prop Types

Check these files have explicit prop types (they do, but verify):

* `IIIFViewer.tsx` - `IIIFViewerProps`
* `ViewerTopBar.tsx` - `ViewerTopBarProps`
* `ZoomedImage.tsx` - `ZoomedImageProps`
* `ImageViewer.tsx` - `ImageViewerProps`
* `MainViewer.tsx` - component props defined inline

All components checked have proper prop types.

### 5. Run TypeScript Compiler

```bash
yarn tsc
```

Fix any errors that appear in `ItemViewer`/`IIIFViewer` files.

### 6. Validate Against Official Specs

Since you're using official IIIF types, verify your custom types align correctly and you're not duplicating them:

Check IIIF Type Usage: Verified custom types properly use official `@iiif/presentation-3` types

```typescript
//  Good: Using official types directly
import { Canvas, Manifest, ContentResource } from '@iiif/presentation-3';

//  Good: Extending official types
export type TransformedCanvas = {
  // Uses official IIIF types as building blocks
  painting: (ChoiceBody | ContentResource)[];
  metadata: MetadataItem[];
};

//  Avoid: Redefining what IIIF already provides
// Don't create your own Canvas type when @iiif/presentation-3 has one
```

#### Wellcome Catalogue API Types:

Your Catalogue API types (`Work`, `WorkBasic`, `Item`, etc.) are manually defined. Consider centralising those types within the organisation.

## Acceptance Criteria

* [ ] Fixed both `setSearchResults` implicit `any` types
* [ ] (Optional) Added `ImageService` type to `content/webapp/types/item-viewer.ts`
* [ ] Documented existing type structure for reference
* [ ] Checked for duplicate type definitions across files
* [ ] `yarn tsc` runs without errors in ItemViewer files
* [ ] All team members understand what types exist and where they live

## What This Phase Achieves

1. Type Safety - No implicit `any` in critical functions
2. Official Types - Verified use of `@iiif/presentation-3` official IIIF types
3. Documentation - Clear understanding of existing types and their sources
4. Foundation - Solid base for refactoring with confidence
5. Consistency - All types follow same patterns and use official specs where available

## Next Steps

**Next:** [Phase 1: Feature Flag Setup](/request-for-comments-rfcs/086-item-viewer-refactor/07-phase-1-feature-flag.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wellcomecollection.org/request-for-comments-rfcs/086-item-viewer-refactor/06-phase-0-type-audit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
