Skip to content

Convert additional Props/Style types to interface - #58062

Closed
huntie wants to merge 1 commit into
react:mainfrom
huntie:fix-definitely-typed-interfaces
Closed

huntie wants to merge 1 commit into
react:mainfrom
huntie:fix-definitely-typed-interfaces

Conversation

@huntie

@huntie huntie commented Aug 21, 2026 •

Copy link
Copy Markdown
Collaborator

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
ImageProps Libraries/Image/ImageProps.js:336 index.d.ts#L1422
PressableStateCallbackType Libraries/Components/Pressable/Pressable.js:36 index.d.ts#L1444
ViewStyle Libraries/StyleSheet/StyleSheet.js.flow:141 index.d.ts#L1458
TextStyle Libraries/StyleSheet/StyleSheet.js.flow:159 index.d.ts#L1486
ImageStyle Libraries/StyleSheet/StyleSheet.js.flow:177 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 @jakebailey

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

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.

@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 Aug 21, 2026
@github-actions

Copy link
Copy Markdown

Warning

JavaScript API change detected

This PR commits an update to ReactNativeApi.d.ts, indicating a change to React Native's public JavaScript API.

  • Please include a clear changelog message.
  • This change will be subject to additional review.

This change was flagged as: POTENTIALLY_BREAKING

@huntie
huntie force-pushed the fix-definitely-typed-interfaces branch from c359385 to 57b788f Compare August 21, 2026 14:58
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Aug 21, 2026
@jakebailey

Copy link
Copy Markdown

Do you have any timeline for when you think this (or a similar PR) might be merged and released? The types break is blocking PRs to any react types on DT.

@huntie

huntie commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

@jakebailey As soon as this gets merged, I'll raise a pick request into the 0.87 branch, then it'll go out in the next patch release (typically Mondays).

cc @zeyap @cortinico

@cortinico

Copy link
Copy Markdown
Contributor

@huntie can you fix the conflicts with main?

@huntie
huntie force-pushed the fix-definitely-typed-interfaces branch from 57b788f to bb0b6be Compare August 26, 2026 12:40
@huntie

huntie commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator Author

@cortinico Done

@meta-codesync

meta-codesync Bot commented Aug 26, 2026

Copy link
Copy Markdown

@cortinico has imported this pull request. If you are a Meta employee, you can view this in D117534044.

@meta-codesync meta-codesync Bot closed this in 593ae02 Aug 27, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Aug 27, 2026
@meta-codesync

meta-codesync Bot commented Aug 27, 2026

Copy link
Copy Markdown

@cortinico merged this pull request in 593ae02.

@huntie
huntie deleted the fix-definitely-typed-interfaces branch August 27, 2026 15:25
@jakebailey

Copy link
Copy Markdown

@jakebailey As soon as this gets merged, I'll raise a pick request into the 0.87 branch, then it'll go out in the next patch release (typically Mondays).

cc @zeyap @cortinico

@huntie I'm not sure that this happened; were you still working on the other breaks? I see #58168 now, but still hoping to get DT unbroken...

@huntie

huntie commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

@jakebailey Yes, opened here: reactwg/react-native-releases#1399. Waiting on the Release Crew to deploy this in the next patch.

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
meta-codesync Bot pushed a commit that referenced this pull request Sep 25, 2026
Summary:
react-native-web and Nativewind extend React Native's types with module augmentation. #58062 made the props and style types interfaces, which cleared the duplicate identifier errors. Two things still can't be extended.

**Styles:** `ViewStyle` is an interface derived from `____ViewStyle_Internal`, but `ViewProps['style']` reads the base, so augmenting `ViewStyle` doesn't reach it:

```ts
declare module 'react-native' {
  interface ViewStyle { transitionDuration?: string }
}

<View style={{ transitionDuration: '1s' }} />;             // error
StyleSheet.create({ box: { transitionDuration: '1s' } });  // error
```

`____ViewStyle_Internal` is now named `ViewStyle`, and the same for Text and Image. `StyleSheet` re-exports each name unchanged, so the interface and the base are one symbol.

**Props written as inline object literals:** The transform copies them into the interface body, where a second declaration is a merge conflict rather than an override, so the augmentation is silently ignored. Eleven of the 24 annotated types are affected. Each now moves its inline members into a private `<Name>Core` alias, so they reach the interface through the extends clause and are inherited, like everything from `ViewProps` already was:

```ts
// before
declare interface KeyboardAvoidingViewProps extends Readonly<ViewProps> {
  readonly enabled?: boolean
}

// after
declare interface KeyboardAvoidingViewProps extends Readonly<
  ViewProps & KeyboardAvoidingViewPropsCore
> {}
```

That costs 11 new names in the API snapshot, one per affected type. `PressableProps` set the precedent with `PressableBaseProps`.

`ImagePropsBase` and `ImageBackgroundProps` declare members that shadow keys of the type they spread, and a Flow spread of an optional property unions the two types instead of replacing the member, so those keys get an explicit `Omit`.

Caveat: an augmented member has to be assignable to the inherited one. Adding a key is clean and narrowing works, but widening raises `TS2430` on the declaration file, which `skipLibCheck: true` silences.

## Changelog:

[GENERAL] [CHANGED] - Allow module augmentation to extend generated props and style types

Pull Request resolved: #58168

Test Plan:
`yarn build-types`: all 24 annotated types now emit an empty interface body. `ViewStyle`, `TextStyle` and `ImageStyle` are unchanged; the props types gain the 11 `<Name>Core` aliases.

Compiled augmentations with `skipLibCheck: false`. Styles: the two lines above pass here and report `TS2353` on `main`. Props: adding a key and narrowing an existing one on each of the 11 types passes here and reports `TS2717` on `main`.

`yarn flow-check`, `yarn test-generated-typescript`, `yarn format-check` and `yarn lint`: clean, apart from 3 Flow errors in `packages/react-native-codegen/lib` already on `main`. `yarn jest packages/react-native/Libraries packages/react-native/src scripts/js-api`: 632 tests pass, no snapshot changed.

Reviewed By: christophpurrer

Differential Revision: D117876097

Pulled By: cortinico

fbshipit-source-id: c0797f14d95a01662930f7158738ea79e1bf1a30
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. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants