Files
react-native/scripts/js-api
Alex Hunt 0fc76bb527 Fix TS exactOptionalPropertyTypes compatibility for generated types (#57628)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57628

NOTE: Patches over a `flow-api-translator` bug, which I'll fix upstream later. We need to pick this to `0.87-stable` to resolve user integration issues.

**Context**

TypeScript's `exactOptionalPropertyTypes` flag (strict mode) creates a distinction between `foo?: T` and `foo?: T | undefined`.

```js
// Flow's semantics

interface Props {
  onRefresh?: () => void;
}
const a: Props = { onRefresh: undefined }; // ✅ ok
```
```ts
// TypeScript with exactOptionalPropertyTypes: true (i.e. strict mode)

interface Props {
  onRefresh?: () => void;
}
const a: Props = { onRefresh: undefined }; // ❌ error

interface PropsFixed {
  onRefresh?: (() => void) | undefined;
}
const b: PropsFixed = { onRefresh: undefined }; // ✅ ok
```

With this added strictness in TypeScript, our generated types via `flow-api-translator` could create downstream type incompatibility in apps.

**This diff**

Patches the above issue in React Native's Flow → TS `types_generated/` pipeline. We transform all instances to the wider `foo?: T | undefined` format, for maximum compatibility.

**Notes**

`foo?: T [| undefined]` **remains stripped** in the API snapshot (existing transform with the aim of a concise format). There is a net, nonfunctional snapshot diff around function members, which (as a positive result) are re-ordered.

Changelog:
[General][Fixed] - **Strict TypeScript API**: Optional property types are now widened to explicitly include `| undefined` for `exactOptionalPropertyTypes` compatibility

Reviewed By: cipolleschi

Differential Revision: D113030161

fbshipit-source-id: 3ab005edab6b80b18fbb9ae7125ba56e3bd94195
2026-07-22 04:50:50 -07:00
..

scripts/js-api

TypeScript build pipeline for React Native's JavaScript API.

Overview

yarn build-types is a custom build pipeline for translating React Native's Flow source code to TypeScript.

Specifically, it reduces the runtime JavaScript API of react-native into two outputs:

  • Generated TypeScript types
    Public user types for react-native, shipped to npm
    packages/react-native/types_generated/
  • ‌Public API snapshot
    Snapshot file of the public API shape, used by maintainers
    packages/react-native/ReactNativeApi.d.ts

Dependencies

yarn build-types makes use of the following dependencies, composed with other pre/post transformation steps and dependency resolution.

Usage

Build generated types + API snapshot

Maintainers should run this script whenever making intentional API changes.

# Build types + API snapshot
yarn build-types [--validate]

# Build types without API snapshot
yarn build-types --skip-snapshot

Diff API snapshot compatibility

This script is run by CI to compare changes to ReactNativeApi.d.ts between commits.

# Compare two versions of the API snapshot
yarn js-api-diff <before.d.ts> <after.d.ts>
{
  "result": "BREAKING",
  "changedApis": [
    "ViewStyle"
  ]
}

Configuration

Sparse configuration options are defined and documented in scripts/js-api/config.js.

About the two output formats

Generated TypeScript types

types_generated/

Directory providing TypeScript user types for the react-native package, distributed via npm.

  • Gitignored.
  • Scoped to the index.d.ts entry point via package.json#exports.
  • Preserves unstable_ and experimental_ APIs.
  • Preserves doc comments.
  • Preserves source file names (for go to definition).

Public API snapshot

ReactNativeApi.d.ts

Provides a human-readable, maintainable reference of the React Native's public JavaScript API, optimized for developers and diff tooling.

  • Committed to the repo.
  • Strips unstable_ and experimental_ APIs.
  • Strips doc comments.
  • Strips source file names (types are merged into a single program).
  • Versions exported APIs with an 8 char SHA hash, which will be updated when any input type dependencies change shape.