Skip to content

Keep null in the TypeScript type of Image.resolveAssetSource - #59713

Open
Hassan1305 wants to merge 1 commit into
react:mainfrom
Hassan1305:fix/resolve-asset-source-null-type
Open

Hassan1305 wants to merge 1 commit into
react:mainfrom
Hassan1305:fix/resolve-asset-source-null-type

Conversation

@Hassan1305

Copy link
Copy Markdown

Summary:

Fixes #59648.

Image.resolveAssetSource returns null for an asset id the registry does not hold, and its Flow type (?ImageResolvedAssetSource) allows that. The generated TypeScript declares ImageResolvedAssetSource | undefined, because replaceNullablePropertiesWithUndefined translates ?T on an object type member to T | undefined. TypeScript code that only rules out undefined therefore compiles and then throws on null.

This moves the return type to a module-level alias, which the transform does not touch, so it generates ImageResolvedAssetSource | null | undefined. The Flow type is unchanged in meaning.

TypeScript users who only check !== undefined will now get a compile error at that line. That is the intended effect, but it can surface in existing code.

The transform affects other object type members too. I kept this change to the one reported method rather than changing the transform, since that would alter much of the public API. The hand-written types_DEPRECATED/Libraries/Image/Image.d.ts also omits null and is unchanged here.

Changelog:

[GENERAL] [FIXED] - Include null in the TypeScript return type of Image.resolveAssetSource

Test Plan:

No test is added: __typetests__ compiles with strict: false, where a missing null can't be detected. Instead I compiled this file with a temporary tsconfig extending __typetests__/tsconfig.json with strict: true, using tsc -p:

import {Image} from 'react-native';
export function issueLine(id: number): string {
  const r = Image.resolveAssetSource(id);
  return r !== undefined ? r.uri : 'missing';
}
export function safeNullish(id: number): string {
  const r = Image.resolveAssetSource(id);
  return r != null ? r.uri : 'missing';
}
export function safeTruthy(id: number): string {
  const r = Image.resolveAssetSource(id);
  return r ? r.uri : 'missing';
}
export const safeChain = (id: number) => Image.resolveAssetSource(id)?.uri;
  • Without this change: compiles with no errors.
  • With this change: only issueLine errors, with error TS18047: 'r' is possibly 'null'.

Commands run locally on Node 24, all passing:

  • node ./scripts/run-ci-javascript-tests.js --maxWorkers 4 (feature flags, lint, API snapshot, Flow, Jest: 262 suites, 6458 passed, 1 skipped)
  • yarn lint-markdown, yarn lint, yarn flow-check
  • yarn test-typescript-legacy
  • yarn build-types --skip-snapshot and yarn test-generated-typescript
  • yarn build-types --validate
  • yarn format-check-javascript

Not run locally: Node 22, analyze_scripts.sh (shellcheck not installed; no shell scripts changed), and the Android, iOS and Fantom jobs (no native code changed).

🤖 Generated with Claude Code

resolveAssetSource returns null for an asset the registry does not hold, but
the generated TypeScript declared `ImageResolvedAssetSource | undefined`:
`?T` on an object type member is translated to `T | undefined`. Move the
return type to a module-level alias, which translates to
`ImageResolvedAssetSource | null | undefined`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@meta-cla

meta-cla Bot commented Oct 31, 2026

Copy link
Copy Markdown

Hi @Hassan1305!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@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

@meta-cla

meta-cla Bot commented Oct 31, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@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 Oct 31, 2026
@meta-cla

meta-cla Bot commented Oct 31, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@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 Oct 31, 2026

This branch has not been deployed

No deployments
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. 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.

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

1 participant