Skip to content

Image.resolveAssetSource's TypeScript declaration drops the null it returns for an unknown asset #59648

Open

Description

@YevheniiKotyrlo

Description

Image.resolveAssetSource returns null for an asset id the asset registry does not hold (resolveAssetSource.js L118-L121), and its Flow type says so: resolveAssetSource(source: ImageSource): ?ImageResolvedAssetSource (ImageTypes.flow.js L62). The generated TypeScript declaration, types_generated/Libraries/Image/ImageTypes.flow.d.ts, declares it as returning ImageResolvedAssetSource | undefined, without the null. TypeScript code that rules out undefined therefore type-checks and then throws on the null the function returns.

Steps to reproduce

  1. Clone https://github.com/YevheniiKotyrlo/react-native-typescript-declarations and run yarn install in ReproducerApp. It runs react-native@0.89.0-nightly-20261029-25b05acd7 with TypeScript 7.0.2.
  2. declarations/resolve-asset-source.ts reads the uri of Image.resolveAssetSource(assetId) once the result is not undefined. Run yarn check:resolve-asset-source, which type-checks it with strict: true.
  3. Run yarn jest __tests__/resolveAssetSource-test.ts. Its first test checks that Image.resolveAssetSource(123456) returns null; its second calls the function from step 2 with that id.

Expected: step 2 reports 'resolved' is possibly 'null', since the function can return null.
Seen: step 2 passes with no errors, the first test of step 3 passes, and the second throws TypeError: Cannot read properties of null (reading 'uri'). 0.88.1 declares the same ImageResolvedAssetSource | undefined.

React Native Version

0.88.1, and 0.89.0-nightly-20261029-25b05acd7

Affected Platforms

Other (please specify)

Output of npx @react-native-community/cli info

System:
  OS: Windows 11 10.0.26300
Binaries:
  Node:
    version: 26.12.1
  Yarn:
    version: 1.22.22
npmPackages:
  "@react-native-community/cli":
    installed: 20.2.0
    wanted: 20.2.0
  react:
    installed: 19.3.0
    wanted: 19.3.0
  react-native:
    installed: 0.89.0-nightly-20261029-25b05acd7
    wanted: 0.89.0-nightly-20261029-25b05acd7

The defect is in the published TypeScript declarations, so it shows on every platform; the reproducer runs tsc and Jest.

Stacktrace or Logs

$ yarn check:resolve-asset-source
(no output; tsc exits 0)

$ yarn jest __tests__/resolveAssetSource-test.ts
FAIL __tests__/resolveAssetSource-test.ts
  √ resolveAssetSource returns null for an asset id the registry does not hold (104 ms)
  × code the declaration accepts reads uri of that null (7 ms)

  ● code the declaration accepts reads uri of that null

    expect(received).not.toThrow()

    Error name:    "TypeError"
    Error message: "Cannot read properties of null (reading 'uri')"

          5 | export function uriOf(assetId: number): string {
          6 |   const resolved = Image.resolveAssetSource(assetId);
        > 7 |   return resolved !== undefined ? resolved.uri : 'missing';
            |                                            ^
          8 | }
          9 |

MANDATORY Reproducer

https://github.com/YevheniiKotyrlo/react-native-typescript-declarations

Screenshots and Videos

None: the failure is the type checker's and Jest's output above.

Activity

  1. YevheniiKotyrlo commented on Oct 30, 2026

    @YevheniiKotyrlo
    ContributorAuthor

    This is the patch I apply to the published 0.88.0 package until a fix lands: the declaration gets back the null that the Flow type ?ImageResolvedAssetSource holds.

    diff --git a/types_generated/Libraries/Image/ImageTypes.flow.d.ts b/types_generated/Libraries/Image/ImageTypes.flow.d.ts
    --- a/types_generated/Libraries/Image/ImageTypes.flow.d.ts
    +++ b/types_generated/Libraries/Image/ImageTypes.flow.d.ts
    @@ -39,7 +39,7 @@ type ImageComponentStaticsIOS = Readonly<{
       /**
        * @see https://reactnative.dev/docs/image#resolveassetsource
        */
    -  resolveAssetSource(source: ImageSource): ImageResolvedAssetSource | undefined;
    +  resolveAssetSource(source: ImageSource): ImageResolvedAssetSource | null | undefined;
     }>;
     type ImageComponentStaticsAndroid = Readonly<Omit<ImageComponentStaticsIOS, "abortPrefetch"> & {
       abortPrefetch(requestId: number): void;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions