Skip to content

fix: replace @ts-ignore with Metro-specific type definitions#832

Open
YevheniiKotyrlo wants to merge 4 commits intostorybookjs:nextfrom
YevheniiKotyrlo:fix/remove-ts-ignore-require-context
Open

fix: replace @ts-ignore with Metro-specific type definitions#832
YevheniiKotyrlo wants to merge 4 commits intostorybookjs:nextfrom
YevheniiKotyrlo:fix/remove-ts-ignore-require-context

Conversation

@YevheniiKotyrlo
Copy link

@YevheniiKotyrlo YevheniiKotyrlo commented Jan 11, 2026

Summary

Removes @ts-ignore comment from generated storybook.requires.ts by providing proper Metro type definitions.

Previous approach (rejected): Added @types/webpack-env as dependency.

New approach (per maintainer feedback): Custom Metro type definitions following the same pattern used by Expo.

Background Research

Metro's require.context API intentionally matches webpack's API by design (Metro PR #822), but the runtime implementations differ. Rather than using webpack types, this PR provides Metro-specific types.

How Expo handles this:

  • Expo manually maintains Metro types at packages/expo/types/metro-require.d.ts
  • Created by Mark Lawlor in PR #24255 (Sept 2023)
  • Uses __MetroModuleApi namespace to avoid conflicts with other type definitions
  • Based on webpack-env types but customized for Metro's implementation

Why not auto-convert from Flow?

  • Metro is written in Flow, not TypeScript
  • Automated Flow-to-TypeScript converters fail on Metro's complex type definitions
  • No one in the ecosystem (Expo, React Native) auto-converts these types
  • Manual types with clear source references is the standard approach

Changes

  1. metro-env.d.ts - New file with Metro type definitions

    • __MetroModuleApi.RequireContext - require.context() return type
    • __MetroModuleApi.RequireFunction - require.context() method signature
    • __MetroModuleApi.Hot - module.hot HMR API
    • Extends NodeJS.Require and NodeModule interfaces
  2. package.json

    • Removed @types/webpack-env dependency
    • Added "./metro-env": "./metro-env.d.ts" export
  3. scripts/generate.js

    • Adds /// <reference types="@storybook/react-native/metro-env" /> to generated TypeScript files

References

Test Plan

  • yarn test:generate passes
  • Generated files include proper type reference
  • No @ts-ignore needed in generated code

The generated `storybook.requires.ts` uses Metro's `require.context` and
`module.hot` APIs, which are copied from webpack. Adding `@types/webpack-env`
as a dependency provides proper TypeScript definitions for consumers.

This follows the precedent established in commit 36ee762:
> "@types/webpack-env must be defined as dependencies in packages that
> export a type/function using typings from @types/webpack-env"

Since @storybook/react-native generates code that consumers compile,
and that code uses require.context/module.hot, this qualifies as
"exporting" code dependent on these types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dannyhw
Copy link
Member

dannyhw commented Jan 11, 2026

Hey thanks for this PR, however I wouldn't want to add this dependency personally.

I understand the intention behind this pr, however I don't think this is the right fix since the metro implementation doesn't match the webpack one and we shouldn't rely on any dependency to webpack in my opinion.

If anything we should copy the type definitions from expo here
https://github.com/expo/expo/blob/main/packages/expo/types/metro-require.d.ts

However its also low priority in my opinion since this ts-ignore exists in a generated file that can be ignored in eslint

Replace @types/webpack-env dependency with custom Metro type definitions,
following the same approach used by Expo.

Metro's require.context API intentionally matches webpack's API by design,
but using webpack types caused concerns about API differences.

This change:
- Adds metro-env.d.ts with Metro-specific types in __MetroModuleApi namespace
- Exports types via @storybook/react-native/metro-env
- Auto-injects reference directive in generated storybook.requires.ts files
- Removes @types/webpack-env dependency

References:
- Expo's approach: https://github.com/expo/expo/blob/main/packages/expo/types/metro-require.d.ts
- Metro require.context PR: facebook/metro#822
- Metro HMR Flow types: https://github.com/facebook/metro/blob/main/packages/metro-runtime/src/polyfills/require.js.flow
@YevheniiKotyrlo YevheniiKotyrlo changed the title fix: remove @ts-ignore by adding @types/webpack-env dependency fix: replace @ts-ignore with Metro-specific type definitions Jan 12, 2026
dannyhw and others added 2 commits January 15, 2026 10:19
- Remove unnecessary 'declare var' statements (module/require already declared by Node types)
- Add eslint-disable for intentional empty interface (declaration merging pattern)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants