Skip to content

Enable Strict TS API by default (#57490) - #57490

Closed
huntie wants to merge 3 commits into
react:mainfrom
huntie:export-D110458670
Closed

huntie wants to merge 3 commits into
react:mainfrom
huntie:export-D110458670

Conversation

@huntie

@huntie huntie commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary:

See RFC0894: Removing deep imports from react-native

This is the big switch to enable the Strict TypeScript API (generated types + single index entry point) by default in React Native.

Opt-in → opt-out

After this change, the main react-native package resolves its "types" entry points only to types_generated/index.d.ts — with no other subpaths available.

The new "react-native-legacy-deep-imports" condition maps to legacy types/ and Libraries/*.d.ts sources.

Impact limitation: For this stage of rollout, the "default" condition continues to resolve to source files. Only TypeScript is affected.

How to opt out

Opposite of today's opt-in, which we will update in the docs. Again, the only impact area today is TypeScript.

// tsconfig.json
{
  "extends": "@react-native/typescript-config",
  "compilerOptions": {
    ...
    "customConditions": ["react-native-legacy-deep-imports"]
  }
}

Other changes

  • Drop @react-native/typescript-config/strict entry point, update README.
  • Update __typetests__.

Rollout plan

Target release: 0.87. This and the contributing stack will be cherry picked for RC1.

  • We've conducted testing against 100+ real Expo codebases, giving us the confidence that we've reduced breaking changes enough that the vast majority of RN codebases can migrate.
  • The Strict API includes a number of intentional breaking changes, and docs have been kept up to date.
  • We're shipping a /migrate-to-strict-api skill to migrate via agents, see Add migrate-to-strict-api skill react-native-community/skills#3.

What's improved since 0.80?

Since the initial opt-in launch of the Strict API in 0.80, we've been making continuous improvements over the last year to get our generated types into a widely launchable state.

Most notably:

Rollback plan

Revert this diff.

IMPORTANT: We'll adopt a policy of super-eager rollback, if there are any unsolvable issues during the RC phase.

Changelog:
[General][Breaking] - React Native's default JavaScript API is now the Strict TypeScript API. Use customConditions: ["react-native-legacy-deep-imports"] to opt out.

Reviewed By: cortinico

Differential Revision: D110458670

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 8, 2026
@meta-codesync

meta-codesync Bot commented Jul 8, 2026

Copy link
Copy Markdown

@huntie has exported this pull request. If you are a Meta employee, you can view the originating Diff in D110458670.

@facebook-github-tools facebook-github-tools Bot added p: Facebook Partner: Facebook Partner labels Jul 8, 2026
@meta-codesync meta-codesync Bot changed the title Enable Strict TS API by default Enable Strict TS API by default (#57490) Jul 9, 2026
@huntie
huntie force-pushed the export-D110458670 branch from 1105931 to 246fc19 Compare July 9, 2026 16:43
huntie added a commit to huntie/react-native that referenced this pull request Jul 9, 2026
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

TODO: Description to come.

Differential Revision: D110458670
huntie added a commit to huntie/react-native that referenced this pull request Jul 9, 2026
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

TODO: Description to come.

Differential Revision: D110458670
@huntie
huntie force-pushed the export-D110458670 branch from 246fc19 to 1d07743 Compare July 9, 2026 18:29
huntie added a commit to huntie/react-native that referenced this pull request Jul 9, 2026
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

TODO: Description to come.

Differential Revision: D110458670
@huntie
huntie force-pushed the export-D110458670 branch from 1d07743 to da00fc8 Compare July 9, 2026 18:36
huntie added a commit to huntie/react-native that referenced this pull request Jul 9, 2026
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

TODO: Finish tidying up description below.

Differential Revision: D110458670
@huntie
huntie force-pushed the export-D110458670 branch from da00fc8 to cc19a4a Compare July 9, 2026 18:37

@cortinico cortinico left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

huntie added 3 commits July 10, 2026 05:56
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

Exposes a `'react-native/react-private-interface'` subpath export on the main package, to replace `Libraries/ReactPrivate/ReactNativePrivateInterface.js`.

**Impact: Internal**

This is a private contract between `react` and `react-native`.

- `ReactNativePrivateInterface` is deprecated and we'll migrate React call sites in a future version before cleanup.

**Naming**

Translate directly to `react-private-interface` ("private interface for React"). There's alternatives here but the explicitness and continuity is helpful, I believe.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D111231527
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

Adds a `'react-native/unstable-internals-do-not-use'` entry point that acts as an explicit, opt-in escape hatch for frameworks and libraries that depend on specific React Native internals.

Follows (and supersedes) react-native-community/discussions-and-proposals#985.

Resolves T270727304.

**Motivation**

- Maintains a known list of which React Native internals are still in use.
- Decouples removal of the Strict API opt-out from the longer-term decisions about these APIs.
- Lets us relocate supporting source files freely, since consumers reference this subpath instead of deep internal paths.

**Notes**

- Reuses the runtime **object-with-getter pattern** (same as `index.js`), to avoid any native module side effects caused by loading adjacent file exports.
    - e.g. in Expo, [`hmrUtils.js`](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/async-require/hmrUtils.native.ts?fbclid=IwY2xjawS7GjNwZG9mA2V4dG4DYWVtAjExAGJyaWQRMTZ1ckEwU05oWUw2bDBVN21zcnRjBmFwcF9pZAEwAAEen3UuX4Ig-RD3n1ULZIHIHq21Mfk_ci9b2SxquY7UkngDs6qhnRt5YQlb8Os_aem_ylJy40egSOl1qhZ9bA9HTA) is designed to be run early in RN startup — preserve the lazy require characteristic and do not break this.
- TypeScript defs on this API are minimal, with complex internal input/handle types reduced to `unknown`. As with D110602194, these are intended to be feature-locked.

**Exposed internals and known consumers**

NOTE: The exports the community needs have reduced slightly since the spreadsheet in RFC0895 and would almost all align with `devsupport`. However, we're explicitly leaving a decision to formalise until later, and we may need to add in extra APIs quickly based on RC feedback.

| Export | Source module | Known consumers |
|---|---|---|
| `AppContainer` | `Libraries/ReactNative/AppContainer` | react-native-screens ([DebugContainer.tsx](https://github.com/software-mansion/react-native-screens/blob/6f38d76129d40cc8145d06b98f885b508fa7bf2d/src/components/DebugContainer.tsx#L5)) |
| `AssetSourceResolver` | `Libraries/Image/AssetSourceResolver` | Re.pack ([IncludeModules.ts](https://github.com/callstack/repack/blob/2498b3a426203daa4b81c7e6f7a88e86d88e77b9/packages/repack/src/modules/IncludeModules.ts#L9)) |
| `customDirectEventTypes` | `Libraries/Renderer/shims/ReactNativeViewConfigRegistry` | react-native-gesture-handler ([customDirectEventTypes.ts](https://github.com/software-mansion/react-native-gesture-handler/blob/ee147abf364bef48a02d3cf437572b4dddd30bec/packages/react-native-gesture-handler/src/handlers/customDirectEventTypes.ts#L2)) |
| `DevLoadingView` | `Libraries/Utilities/DevLoadingView` | Expo ([hmrUtils.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/async-require/hmrUtils.native.ts)), Re.pack ([WebpackHMRClient.ts](https://github.com/callstack/repack/blob/2498b3a426203daa4b81c7e6f7a88e86d88e77b9/packages/repack/src/modules/WebpackHMRClient.ts)) |
| `getDevServer` | `Libraries/Core/Devtools/getDevServer` | Expo ([getDevServer.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/async-require/getDevServer.native.ts), [hmrUtils.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/async-require/hmrUtils.native.ts), [base.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/dom/base.ts), [getDevServer.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/metro-runtime/src/getDevServer.native.ts), [devServerEndpoints.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/log-box/src/utils/devServerEndpoints.ts), [getConnectionInfo.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/devtools/src/getConnectionInfo.native.ts), [index.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo-router/src/getDevServer/index.native.ts)) |
| `HMRClient` | `Libraries/Utilities/HMRClient` | Expo ([metroServerLogs.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/metro-runtime/src/metroServerLogs.native.ts)) |
| `NativeExceptionsManager` | `Libraries/Core/NativeExceptionsManager` | Expo ([hmrUtils.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/async-require/hmrUtils.native.ts)), Re.pack ([WebpackHMRClient.ts](https://github.com/callstack/repack/blob/2498b3a426203daa4b81c7e6f7a88e86d88e77b9/packages/repack/src/modules/WebpackHMRClient.ts)) |
| `NativeRedBox` | `Libraries/NativeModules/specs/NativeRedBox` | Expo ([hmrUtils.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/async-require/hmrUtils.native.ts)), Re.pack ([WebpackHMRClient.ts](https://github.com/callstack/repack/blob/2498b3a426203daa4b81c7e6f7a88e86d88e77b9/packages/repack/src/modules/WebpackHMRClient.ts)) |
| `NativeSourceCode` | `Libraries/NativeModules/specs/NativeSourceCode` | Expo ([getBundleUrl.native.ts](https://github.com/expo/expo/blob/2d07e3a17f4be2284bbf579d8825fe32f762ce1a/packages/expo/src/utils/getBundleUrl.native.ts)) |
| `PressabilityDebugView` | `Libraries/Pressability/PressabilityDebug` | react-native-gesture-handler ([PressabilityDebugView.tsx](https://github.com/software-mansion/react-native-gesture-handler/blob/ee147abf364bef48a02d3cf437572b4dddd30bec/packages/react-native-gesture-handler/src/handlers/PressabilityDebugView.tsx#L2)) |

**Alternative names**

- `unstable-frameworks`
- `unstable-devsupport`
- `frameworks-private-interface` (mirroring `ReactPrivateInterface.js`) — this is likely a future stable shape candidate.

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D110911864
Summary:

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

TODO: Finish tidying up description below.

Reviewed By: cortinico

Differential Revision: D110458670
@huntie
huntie force-pushed the export-D110458670 branch from cc19a4a to 0441eec Compare July 10, 2026 12:57
@meta-codesync meta-codesync Bot closed this in c948b61 Jul 10, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Jul 10, 2026
@meta-codesync

meta-codesync Bot commented Jul 10, 2026

Copy link
Copy Markdown

This pull request has been merged in c948b61.

huntie added a commit to huntie/react-native that referenced this pull request Jul 10, 2026
Summary:
Pull Request resolved: react#57490

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

This is the **big switch** to enable the Strict TypeScript API (generated types + single index entry point) by default in React Native.

**Opt-in → opt-out**

After this change, the main `react-native` package resolves its `"types"` entry points only to `types_generated/index.d.ts` — with no other subpaths available.

The new `"react-native-legacy-deep-imports"` condition maps to legacy `types/` and `Libraries/*.d.ts` sources.

**Impact limitation**: For this stage of rollout, the `"default"` condition continues to resolve to source files. Only TypeScript is affected.

**How to opt out**

Opposite of today's opt-in, which we will update in [the docs](https://reactnative.dev/docs/strict-typescript-api). Again, the only impact area today is **TypeScript**.

```json5
// tsconfig.json
{
  "extends": "react-native/typescript-config",
  "compilerOptions": {
    ...
    "customConditions": ["react-native-legacy-deep-imports"]
  }
}
```

**Other changes**

- Drop `react-native/typescript-config/strict` entry point, update README.
- Update `__typetests__`.

**Rollout plan**

**Target release: 0.87**. This and the contributing stack will be cherry picked for RC1.

- We've conducted testing against 100+ real Expo codebases, giving us the confidence that we've reduced breaking changes enough that the vast majority of RN codebases can migrate.
- The Strict API includes a number of **intentional breaking changes**, and docs have been kept up to date.
- We're shipping a `/migrate-to-strict-api` skill to migrate via agents, see react-native-community/skills#3.

**What's improved since 0.80?**

Since the initial opt-in launch of the Strict API in 0.80, we've been making continuous improvements over the last year to get our generated types into a widely launchable state.

Most notably:

- 21+ new/updated root APIs and fixes due to community feedback ([discussion](react-native-community/discussions-and-proposals#893), [PRs](https://github.com/react/react-native/pulls?q=is%3Apr%20label%3A%22JS%20API%20stabilization%20(1.0)%22%20is%3Aclosed)).
- Upstream encapsulation blocker in TypeScript, fixed in 6.0 (react#53565).
- Tailwind/Uniwind compatibility (`interface` types for props).
- `*Instance` ref type exports for all built-in components (react-native-community/discussions-and-proposals#1003).
- Fixes to previously mistyped, high impact APIs, such as `Appearance`.
- New subpath entry points for `asset-registry`, `setup-env`, and others.
- Refinements to doc comments/type translation build.

**Rollback plan**

Revert this diff.

IMPORTANT: We'll adopt a policy of **super-eager rollback**, if there are any unsolvable issues during the RC phase.

Changelog:
[General][Breaking] - React Native's default JavaScript API is now the [Strict TypeScript API](https://reactnative.dev/docs/strict-typescript-api). Use `customConditions: ["react-native-legacy-deep-imports"]` to opt out.

Reviewed By: cortinico

Differential Revision: D110458670

fbshipit-source-id: 4b0e0b458a5f895f783d6d936e7b11ccff2df076
@huntie
huntie deleted the export-D110458670 branch July 10, 2026 16:46
zeyap pushed a commit that referenced this pull request Jul 13, 2026
Summary:
Pull Request resolved: #57490

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

This is the **big switch** to enable the Strict TypeScript API (generated types + single index entry point) by default in React Native.

**Opt-in → opt-out**

After this change, the main `react-native` package resolves its `"types"` entry points only to `types_generated/index.d.ts` — with no other subpaths available.

The new `"react-native-legacy-deep-imports"` condition maps to legacy `types/` and `Libraries/*.d.ts` sources.

**Impact limitation**: For this stage of rollout, the `"default"` condition continues to resolve to source files. Only TypeScript is affected.

**How to opt out**

Opposite of today's opt-in, which we will update in [the docs](https://reactnative.dev/docs/strict-typescript-api). Again, the only impact area today is **TypeScript**.

```json5
// tsconfig.json
{
  "extends": "react-native/typescript-config",
  "compilerOptions": {
    ...
    "customConditions": ["react-native-legacy-deep-imports"]
  }
}
```

**Other changes**

- Drop `react-native/typescript-config/strict` entry point, update README.
- Update `__typetests__`.

**Rollout plan**

**Target release: 0.87**. This and the contributing stack will be cherry picked for RC1.

- We've conducted testing against 100+ real Expo codebases, giving us the confidence that we've reduced breaking changes enough that the vast majority of RN codebases can migrate.
- The Strict API includes a number of **intentional breaking changes**, and docs have been kept up to date.
- We're shipping a `/migrate-to-strict-api` skill to migrate via agents, see react-native-community/skills#3.

**What's improved since 0.80?**

Since the initial opt-in launch of the Strict API in 0.80, we've been making continuous improvements over the last year to get our generated types into a widely launchable state.

Most notably:

- 21+ new/updated root APIs and fixes due to community feedback ([discussion](react-native-community/discussions-and-proposals#893), [PRs](https://github.com/react/react-native/pulls?q=is%3Apr%20label%3A%22JS%20API%20stabilization%20(1.0)%22%20is%3Aclosed)).
- Upstream encapsulation blocker in TypeScript, fixed in 6.0 (#53565).
- Tailwind/Uniwind compatibility (`interface` types for props).
- `*Instance` ref type exports for all built-in components (react-native-community/discussions-and-proposals#1003).
- Fixes to previously mistyped, high impact APIs, such as `Appearance`.
- New subpath entry points for `asset-registry`, `setup-env`, and others.
- Refinements to doc comments/type translation build.

**Rollback plan**

Revert this diff.

IMPORTANT: We'll adopt a policy of **super-eager rollback**, if there are any unsolvable issues during the RC phase.

Changelog:
[General][Breaking] - React Native's default JavaScript API is now the [Strict TypeScript API](https://reactnative.dev/docs/strict-typescript-api). Use `customConditions: ["react-native-legacy-deep-imports"]` to opt out.

Reviewed By: cortinico

Differential Revision: D110458670

fbshipit-source-id: 4b0e0b458a5f895f783d6d936e7b11ccff2df076
m-bert added a commit to software-mansion/react-native-gesture-handler that referenced this pull request Jul 20, 2026
## Description

Since React Native 0.87, Strict TS API is [enabled by default
](react/react-native#57490). This PR brings
necessary changes to resolve ts-errors on 0.87.

This PR also removes `cursor: undefined;` from `iOS`, but now it is a
valid prop - this workaround was necessary on old arch

## Test plan

`yarn ts-check`
leotm added a commit to leotm/react-native-template-new-architecture that referenced this pull request Jul 20, 2026
- 0.88.0-nightly-20260720-e64027865
  - react/react-native@e04ff69...e640278
- Bump RN deps and devDeps (@react-native: babel/jest preset, eslint/metro/ts configs)
- Bump Jest snapshot test rendered RN ver
- Update lockfiles (Yarn, CocoaPods)
- Update iOS privacy manifest
- Bump ReadMe ver
- Opt out of RN default Strict TS API for RNsafeareacontext
  - react/react-native#57490
  - #2041
- @lavamoat/react-native-lockdown unaffected by
  - react/react-native#57482 deprecated rn-get-polyfills unused
  - react/react-native#57475
    - only hooking into Metro serializer opts getPolyfills and getRunModuleStatement
    - react-native/packages/community-cli-plugin: getModulesRunBeforeMainModule updated from /Libraries/Core/InitializeCore to /setup-env in core

Resolve: #2031
leotm added a commit to leotm/react-native-template-new-architecture that referenced this pull request Aug 12, 2026
- react/react-native#57490 example overwrites react-native by mistake
- preserve react-native config like github.com/react/react-native/tree/main/packages/typescript-config
@jakebailey

Copy link
Copy Markdown

This broke a lot of DefinitelyTyped packages: DefinitelyTyped/DefinitelyTyped#75402

In particular, changing from interfaces to type aliases means that the types can no longer be extended, which breaks react-native-web, which extends certain types with web specific extras.

I don't think that interfaces are really any less strict than type aliases, and are a breaking change for any types out there using the fact that they're interfaces.

Would you consider undoing some of this?

@huntie

huntie commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

@jakebailey Which version did you test and which types collided? This is something we directly addressed in 0.87 — and if there's extra gaps, we can adjust.

@jakebailey

Copy link
Copy Markdown

DT is unpinned, so it's the latest.

If you look at https://github.com/DefinitelyTyped/DefinitelyTyped/actions/runs/32138113480, all failures (except maybe one or two) are due to react-native. The PR linked above shows the full set, but mainly it's react-native-web that has the problem.

meta-codesync Bot pushed a commit that referenced this pull request Aug 26, 2026
#58102)

Summary:
`codegenNativeComponent()` declared its return type as `NativeComponentType<Props>`. That alias lives in `Libraries/Utilities/codegenNativeComponent.js` and is not re-exported from the `react-native` root, and the package's `exports` map has no `./types_generated/*` subpath, so the deep specifier is not resolvable either.

As a result, any library that calls `codegenNativeComponent()` and emits declaration files fails to build under `moduleResolution: node16/nodenext/bundler` - TypeScript cannot name the inferred return type portably:

```
src/ReactNativeTestViewNativeComponent.ts:11:1 - error TS2883: The inferred type of 'default' cannot be named without a reference to 'NativeComponentType' from '../node_modules/react-native/types_generated/Libraries/Utilities/codegenNativeComponent'. This is likely not portable. A type annotation is necessary.

  11 export default codegenNativeComponent<NativeProps>('ReactNativeTestView');
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

This is the default `fabric-view` template from `create-react-native-library`, so every new Fabric view library hits it.
It used to work before RN 0.87.0, until #57490 has removed visibility of the internally exported types.

Example of breakage - this test run in `react-native-builder-bob`: https://github.com/callstack/react-native-builder-bob/actions/runs/32675382955/job/97282442650#step:19:20

### Fix

The fix is to declare the return type as `HostComponent<Props>` instead. `NativeComponentType<T>` is defined as `HostComponent<T>`, but only `HostComponent` is exported from root. Consumers can reach it via `import('react-native').HostComponent<Props>`.

## Changelog:

[GENERAL] [FIXED] - Fix TS2883 when building declaration files for libraries that use `codegenNativeComponent` due to unreachable `NativeComponentType<T>`

Pull Request resolved: #58102

Test Plan: Tested locally on a library generated with Bob.

Reviewed By: cipolleschi

Differential Revision: D117336232

Pulled By: fabriziocucci

fbshipit-source-id: 173fcfbc568cc4a8e79c32d16fbcee988db9b104
meta-codesync Bot pushed a commit that referenced this pull request Aug 27, 2026
Summary:
In response to this comment: #57490 (comment)

The DefinitelyTyped `react-native-web` types augment the `react-native` module to layer web-only props and style values onto React Native's types. Module augmentation only works against `interface` declarations, so these hit `error TS2300: Duplicate identifier`.

This was solved in #56809 — this diff extends `interface` emission to additional types as below.

**Changes**

Annotate the remaining types that `types/react-native-web` augments with `build-types emit-as-interface`:

- `AccessibilityProps`
- `ImageProps`
- `PressableStateCallbackType`
- `ViewStyle`, `TextStyle`, `ImageStyle`

**Source for matched `types/react-native-web` conflicts**

| Type | Declared in | Augmented by `types/react-native-web` |
| --- | --- | --- |
| `AccessibilityProps` | `Libraries/Components/View/ViewAccessibility.js:342` | [index.d.ts#L1272](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1272) |
| `ImageProps` | `Libraries/Image/ImageProps.js:336` | [index.d.ts#L1422](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1422) |
| `PressableStateCallbackType` | `Libraries/Components/Pressable/Pressable.js:36` | [index.d.ts#L1444](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1444) |
| `ViewStyle` | `Libraries/StyleSheet/StyleSheet.js.flow:141` | [index.d.ts#L1458](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1458) |
| `TextStyle` | `Libraries/StyleSheet/StyleSheet.js.flow:159` | [index.d.ts#L1486](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1486) |
| `ImageStyle` | `Libraries/StyleSheet/StyleSheet.js.flow:177` | [index.d.ts#L1514](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1514) |

**Not fixed**

The remaining DT failures (parsed from https://github.com/DefinitelyTyped/DefinitelyTyped/actions/runs/32138113480) aren't interface issues:

- `InteractionManager` has no export in the Strict API at all.
- `VirtualizedListProps` is genuinely non-generic in the Flow source (`packages/virtualized-lists/Lists/VirtualizedListProps.js:287`), and `getItem` / `getItemCount` are required there. DT's `VirtualizedListProps<ItemT>` with those omitted is an assumption carried over from the old hand-written types.
- The `ViewStyle` / `TextStyle` / `ImageStyle` "incorrectly extends `WebStyle`" errors **will persist**. RN's `DimensionValue` includes `null`, and DT redefines `bottom?: CSSProperties["bottom"] | DimensionValue` on an interface extending `WebStyle`, whose `bottom` does not accept `null`. DT needs `Exclude<DimensionValue, null>` there. Expect 3 of the 16 reported errors to remain once the duplicate-identifier ones clear.

cc rjbailey

Changelog:
[General][Fixed] - **JS API**: Additional Props/Style types are now defined as `interface`, fixing compatibility with certain DefinitelyTyped packages

Pull Request resolved: #58062

Test Plan:
- `node ./scripts/js-api/build-types` — snapshot regenerated; `--validate` passes
- `yarn test-generated-typescript`, `yarn test-typescript` — pass
- `yarn jest scripts/js-api` — 141 tests pass
- Scratch project replaying react-native-web's augmentations against `types_generated`: all six now merge cleanly. As a control, augmenting `ImagePropsAndroid` (still a type alias) in the same harness reproduces `error TS2300: Duplicate identifier`, confirming the harness detects the failure mode.

Reviewed By: cipolleschi

Differential Revision: D117534044

Pulled By: cortinico

fbshipit-source-id: 8fc37375f7a3d9ea86e1a206059d365b38658231
xesrevinu pushed a commit to opraying/react-native-macos that referenced this pull request Aug 30, 2026
Summary:
Pull Request resolved: react#57490

See [**RFC0894: Removing deep imports from react-native**](react-native-community/discussions-and-proposals#894)

This is the **big switch** to enable the Strict TypeScript API (generated types + single index entry point) by default in React Native.

**Opt-in → opt-out**

After this change, the main `react-native` package resolves its `"types"` entry points only to `types_generated/index.d.ts` — with no other subpaths available.

The new `"react-native-legacy-deep-imports"` condition maps to legacy `types/` and `Libraries/*.d.ts` sources.

**Impact limitation**: For this stage of rollout, the `"default"` condition continues to resolve to source files. Only TypeScript is affected.

**How to opt out**

Opposite of today's opt-in, which we will update in [the docs](https://reactnative.dev/docs/strict-typescript-api). Again, the only impact area today is **TypeScript**.

```json5
// tsconfig.json
{
  "extends": "react-native/typescript-config",
  "compilerOptions": {
    ...
    "customConditions": ["react-native-legacy-deep-imports"]
  }
}
```

**Other changes**

- Drop `react-native/typescript-config/strict` entry point, update README.
- Update `__typetests__`.

**Rollout plan**

**Target release: 0.87**. This and the contributing stack will be cherry picked for RC1.

- We've conducted testing against 100+ real Expo codebases, giving us the confidence that we've reduced breaking changes enough that the vast majority of RN codebases can migrate.
- The Strict API includes a number of **intentional breaking changes**, and docs have been kept up to date.
- We're shipping a `/migrate-to-strict-api` skill to migrate via agents, see react-native-community/skills#3.

**What's improved since 0.80?**

Since the initial opt-in launch of the Strict API in 0.80, we've been making continuous improvements over the last year to get our generated types into a widely launchable state.

Most notably:

- 21+ new/updated root APIs and fixes due to community feedback ([discussion](react-native-community/discussions-and-proposals#893), [PRs](https://github.com/react/react-native/pulls?q=is%3Apr%20label%3A%22JS%20API%20stabilization%20(1.0)%22%20is%3Aclosed)).
- Upstream encapsulation blocker in TypeScript, fixed in 6.0 (react#53565).
- Tailwind/Uniwind compatibility (`interface` types for props).
- `*Instance` ref type exports for all built-in components (react-native-community/discussions-and-proposals#1003).
- Fixes to previously mistyped, high impact APIs, such as `Appearance`.
- New subpath entry points for `asset-registry`, `setup-env`, and others.
- Refinements to doc comments/type translation build.

**Rollback plan**

Revert this diff.

IMPORTANT: We'll adopt a policy of **super-eager rollback**, if there are any unsolvable issues during the RC phase.

Changelog:
[General][Breaking] - React Native's default JavaScript API is now the [Strict TypeScript API](https://reactnative.dev/docs/strict-typescript-api). Use `customConditions: ["react-native-legacy-deep-imports"]` to opt out.

Reviewed By: cortinico

Differential Revision: D110458670

fbshipit-source-id: 4b0e0b458a5f895f783d6d936e7b11ccff2df076
shashikant-panchal pushed a commit to shashikant-panchal/react-native that referenced this pull request Sep 10, 2026
Summary:
In response to this comment: react#57490 (comment)

The DefinitelyTyped `react-native-web` types augment the `react-native` module to layer web-only props and style values onto React Native's types. Module augmentation only works against `interface` declarations, so these hit `error TS2300: Duplicate identifier`.

This was solved in react#56809 — this diff extends `interface` emission to additional types as below.

**Changes**

Annotate the remaining types that `types/react-native-web` augments with `build-types emit-as-interface`:

- `AccessibilityProps`
- `ImageProps`
- `PressableStateCallbackType`
- `ViewStyle`, `TextStyle`, `ImageStyle`

**Source for matched `types/react-native-web` conflicts**

| Type | Declared in | Augmented by `types/react-native-web` |
| --- | --- | --- |
| `AccessibilityProps` | `Libraries/Components/View/ViewAccessibility.js:342` | [index.d.ts#L1272](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1272) |
| `ImageProps` | `Libraries/Image/ImageProps.js:336` | [index.d.ts#L1422](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1422) |
| `PressableStateCallbackType` | `Libraries/Components/Pressable/Pressable.js:36` | [index.d.ts#L1444](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1444) |
| `ViewStyle` | `Libraries/StyleSheet/StyleSheet.js.flow:141` | [index.d.ts#L1458](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1458) |
| `TextStyle` | `Libraries/StyleSheet/StyleSheet.js.flow:159` | [index.d.ts#L1486](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1486) |
| `ImageStyle` | `Libraries/StyleSheet/StyleSheet.js.flow:177` | [index.d.ts#L1514](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/df17ec34853e80dac955a0c2649cec989d90b2b5/types/react-native-web/index.d.ts#L1514) |

**Not fixed**

The remaining DT failures (parsed from https://github.com/DefinitelyTyped/DefinitelyTyped/actions/runs/32138113480) aren't interface issues:

- `InteractionManager` has no export in the Strict API at all.
- `VirtualizedListProps` is genuinely non-generic in the Flow source (`packages/virtualized-lists/Lists/VirtualizedListProps.js:287`), and `getItem` / `getItemCount` are required there. DT's `VirtualizedListProps<ItemT>` with those omitted is an assumption carried over from the old hand-written types.
- The `ViewStyle` / `TextStyle` / `ImageStyle` "incorrectly extends `WebStyle`" errors **will persist**. RN's `DimensionValue` includes `null`, and DT redefines `bottom?: CSSProperties["bottom"] | DimensionValue` on an interface extending `WebStyle`, whose `bottom` does not accept `null`. DT needs `Exclude<DimensionValue, null>` there. Expect 3 of the 16 reported errors to remain once the duplicate-identifier ones clear.

cc rjbailey

Changelog:
[General][Fixed] - **JS API**: Additional Props/Style types are now defined as `interface`, fixing compatibility with certain DefinitelyTyped packages

Pull Request resolved: react#58062

Test Plan:
- `node ./scripts/js-api/build-types` — snapshot regenerated; `--validate` passes
- `yarn test-generated-typescript`, `yarn test-typescript` — pass
- `yarn jest scripts/js-api` — 141 tests pass
- Scratch project replaying react-native-web's augmentations against `types_generated`: all six now merge cleanly. As a control, augmenting `ImagePropsAndroid` (still a type alias) in the same harness reproduces `error TS2300: Duplicate identifier`, confirming the harness detects the failure mode.

Reviewed By: cipolleschi

Differential Revision: D117534044

Pulled By: cortinico

fbshipit-source-id: 8fc37375f7a3d9ea86e1a206059d365b38658231
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants