From e8b963a711635a7e1c992d5784e2abd2c3317507 Mon Sep 17 00:00:00 2001 From: jslok Date: Wed, 9 Sep 2026 16:37:02 -0700 Subject: [PATCH] fix(types): support React Native 0.87 Strict TypeScript API RN 0.87 makes the Strict TypeScript API the default, which breaks two type-level assumptions in this package: - `react-native/Libraries/*` subpaths now resolve to `types: null`, so the deep `CodegenTypes` import has no types. RN re-exports the same types as a `CodegenTypes` namespace from the package root; `WithDefault` resolves identically, so codegen output is unchanged. - `View` is a function component, not a class, so it is no longer usable as a ref instance type. `React.ComponentRef` resolves to the instance type under both the legacy and strict typings. Verified with `tsc --noEmit` against react-native 0.87.1 in an app that uses both `captureRef` and ``. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01C55VgRJc8C6jJdtq1xZgLe --- src/index.tsx | 6 +++--- src/specs/NativeRNViewShot.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 59e3c91..584c073 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -312,7 +312,7 @@ function checkCompatibleProps(props: ViewShotProperties): void { * method is attached to that node for the imperative `ref.current.capture()` * usage. */ -export type ViewShotRef = View & { +export type ViewShotRef = React.ComponentRef & { capture: () => Promise; }; @@ -328,7 +328,7 @@ const ViewShotComponent = forwardRef( style, } = props; - const rootRef = useRef(null); + const rootRef = useRef | null>(null); const rafRef = useRef(null); const lastCapturedURIRef = useRef(null); const resolveFirstLayoutRef = useRef<((layout: unknown) => void) | null>( @@ -378,7 +378,7 @@ const ViewShotComponent = forwardRef( ); const setRootRef = useCallback( - (node: View | null): void => { + (node: React.ComponentRef | null): void => { rootRef.current = node; if (node) (node as ViewShotRef).capture = capture; if (typeof ref === "function") { diff --git a/src/specs/NativeRNViewShot.ts b/src/specs/NativeRNViewShot.ts index cf1eeb7..260a5c8 100644 --- a/src/specs/NativeRNViewShot.ts +++ b/src/specs/NativeRNViewShot.ts @@ -1,6 +1,6 @@ import type {TurboModule} from "react-native"; import {TurboModuleRegistry, NativeModules} from "react-native"; -import {WithDefault} from "react-native/Libraries/Types/CodegenTypes"; +import type {CodegenTypes} from "react-native"; // Options stay `Object` (codegen → ReadableMap / NSDictionary). // Narrowing here would force a coordinated change to both native module @@ -8,7 +8,7 @@ import {WithDefault} from "react-native/Libraries/Types/CodegenTypes"; export interface Spec extends TurboModule { releaseCapture: (uri: string) => void; captureRef: ( - target: WithDefault, + target: CodegenTypes.WithDefault, withOptions: Object, ) => Promise; captureScreen: (options: Object) => Promise;