PageSourceSearch

https://reactnative.dev/assets/js/fcb27031.ce1d4c8e.js

js reactnative.dev collected 2026-09-24 07:16:48 UTC 18,472 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkreact_native_website=self.webpackChunkreact_native_website||[]).push([["1360"],{50871(e,n,i){i.r(n),i.d(n,{metadata:()=>t,default:()=>p,frontMatter:()=>c,contentTitle:()=>a,toc:()=>l,assets:()=>d});var t=JSON.parse('{"id":"strict-typescript-api","title":"Strict TypeScript API (opt in)","description":"The Strict TypeScript API is a preview of our future, stable JavaScript API for React Native.","source":"@site/versioned_docs/version-0.83/strict-typescript-api.md","sourceDirName":".","slug":"/strict-typescript-api","permalink":"/docs/0.83/strict-typescript-api","draft":false,"unlisted":false,"editUrl":"[{\\"label\\":\\"Edit page for next release\\",\\"href\\":\\"https://github.com/facebook/react-native-website/edit/main/docs/strict-typescript-api.md\\"},{\\"label\\":\\"Edit page for 0.83 release\\",\\"href\\":\\"https://github.com/facebook/react-native-website/edit/main/website/versioned_docs/version-0.83/strict-typescript-api.md\\"}]","tags":[],"version":"0.83","lastUpdatedAt":1776064644000,"frontMatter":{"id":"strict-typescript-api","title":"Strict TypeScript API (opt in)"},"sidebar":"docs","previous":{"title":"Using TypeScript","permalink":"/docs/0.83/typescript"},"next":{"title":"Upgrading to new versions","permalink":"/docs/0.83/upgrading"}}'),s=i(62540),r=i(43023),o=i(9384);let c={id:"strict-typescript-api",title:"Strict TypeScript API (opt in)"},a,d={},l=[{value:"Opting in",id:"opting-in",level:2},{value:"Migration guide",id:"migration-guide",level:2},{value:"Codegen types should now be imported from the <code>react-native</code> package",id:"codegen-types-should-now-be-imported-from-the-react-native-package",level:3},{value:"Removal of <code>*Static</code> types",id:"removal-of-static-types",level:3},{value:"Some core components are now function components instead of class components",id:"some-core-components-are-now-function-components-instead-of-class-components",level:3},{value:"Other breaking changes",id:"other-breaking-changes",level:2},{value:"Changes to Animated types",id:"changes-to-animated-types",level:3},{value:"Unified types for optional props",id:"unified-types-for-optional-props",level:3},{value:"Removal of some deprecated types",id:"removal-of-some-deprecated-types",level:3},{value:"Removal of leftover component props",id:"removal-of-leftover-component-props",level:3},{value:"Previously accessible private type helpers may now be removed",id:"previously-accessible-private-type-helpers-may-now-be-removed",level:3}];function h(e){let n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"The Strict TypeScript API is a preview of our future, stable JavaScript API for React Native."}),"\n",(0,s.jsxs)(n.p,{children:["Specifically, this is a new set of TypeScript types for the ",(0,s.jsx)(n.code,{children:"react-native"})," npm package, available from 0.80 onwards. These provide stronger and more futureproof type accuracy, and will allow us to confidently evolve React Native's API into a stable shape. Opting in to the Strict TypeScript API brings some structural type differences, and is therefore a one-time breaking change."]}),"\n",(0,s.jsx)(n.p,{children:"The new types are:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Generated directly from our source code"})," \u2014\xa0improving coverage and correctness, so you can expect stronger compatibility guarantees."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:["Restricted to ",(0,s.jsx)(n.code,{children:"react-native"}),"'s index file"]})," \u2014\xa0more tightly defining our public API, and meaning we won't break the API when making internal file changes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When the community is ready, the Strict TypeScript API will become our default API in future \u2014 synchronized with deep imports removal."}),"\n",(0,s.jsx)(n.h2,{id:"opting-in",children:"Opting in"}),"\n",(0,s.jsxs)(n.p,{children:["We're shipping these new types alongside our existing types,\xa0meaning you can choose to migrate when ready. We encourage early adopters and newly created apps to opt in via your ",(0,s.jsx)(n.code,{children:"tsconfig.json"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["Opting in is a ",(0,s.jsx)(n.strong,{children:"breaking change"}),", since some of our new types have updated names and shapes, although many apps won't be affected. You can learn about each breaking change in the next section."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:'title="tsconfig.json"',children:'{\n  "extends": "@react-native/typescript-config",\n  "compilerOptions": {\n    ...\n    "customConditions": ["react-native-strict-api"]\n  }\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{title:"Under the hood",type:"note",children:(0,s.jsxs)(n.p,{children:["This will instruct TypeScript to resolve ",(0,s.jsx)(n.code,{children:"react-native"})," types from our new ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/react-native?activeTab=code",children:(0,s.jsx)(n.code,{children:"types_generated/"})})," dir, instead of the previous ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/react-native?activeTab=code",children:(0,s.jsx)(n.code,{children:"types/"})})," dir (manually maintained). No restart of TypeScript or your editor is required."]})}),"\n",(0,s.jsxs)(n.p,{children:["The Strict TypeScript API follows our ",(0,s.jsx)(n.a,{href:"https://github.com/react-native-community/discussions-and-proposals/pull/894",children:"RFC"})," to remove deep imports from React Native. Therefore, some APIs are no longer exported at root. This is intentional, in order to reduce the overall surface area of React Native's API."]}),"\n",(0,s.jsxs)(n.admonition,{title:"API feedback",type:"tip",children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sending feedback"}),": We will be working with the community to finalize which APIs we export over (at least) the next two React Native releases. Please share your feedback in our ",(0,s.jsx)(n.a,{href:"https://github.com/react-native-community/discussions-and-proposals/discussions/893",children:"feedback thread"}),"."]}),(0,s.jsxs)(n.p,{children:["See also our ",(0,s.jsx)(n.a,{href:"/blog/2025/06/12/moving-towards-a-stable-javascript-api",children:"announcement blog post"})," for more info on our motivation and timelines."]})]}),"\n",(0,s.jsx)(n.h2,{id:"migration-guide",children:"Migration guide"}),"\n",(0,s.jsxs)(n.h3,{id:"codegen-types-should-now-be-imported-from-the-react-native-package",children:["Codegen types should now be imported from the ",(0,s.jsx)(n.code,{children:"react-native"})," package"]}
1),"\n",(0,s.jsxs)(n.p,{children:["Types used for codegen, like ",(0,s.jsx)(n.code,{children:"Int32"}),", ",(0,s.jsx)(n.code,{children:"Double"}),", ",(0,s.jsx)(n.code,{children:"WithDefault"})," etc. are now available under a single ",(0,s.jsx)(n.code,{children:"CodegenTypes"})," namespace. Similarly, ",(0,s.jsx)(n.code,{children:"codegenNativeComponent"})," and ",(0,s.jsx)(n.code,{children:"codegenNativeCommands"})," are now available to import from the react-native package instead of using the deep import."]}),"\n",(0,s.jsxs)(n.p,{children:["Namespaced ",(0,s.jsx)(n.code,{children:"CodegenTypes"})," as well as ",(0,s.jsx)(n.code,{children:"codegenNativeCommands"})," and ",(0,s.jsx)(n.code,{children:"codegenNativeComponent"})," are also available from ",(0,s.jsx)(n.code,{children:"react-native"})," package when the Strict API is not enabled to make the adoption easier for third-party libraries."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Before"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'title=""',children:"import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';\nimport type {\n  Int32,\n  WithDefault,\n} from 'react-native/Libraries/Types/CodegenTypes';\n\ninterface NativeProps extends ViewProps {\n  enabled?: WithDefault<boolean, true>;\n  size?: Int32;\n}\n\nexport default codegenNativeComponent<NativeProps>(\n  'RNCustomComponent',\n);\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"After"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'title=""',children:"import {CodegenTypes, codegenNativeComponent} from 'react-native';\n\ninterface NativeProps extends ViewProps {\n  enabled?: CodegenTypes.WithDefault<boolean, true>;\n  size?: CodegenTypes.Int32;\n}\n\nexport default codegenNativeComponent<NativeProps>(\n  'RNCustomComponent',\n);\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"removal-of-static-types",children:["Removal of ",(0,s.jsx)(n.code,{children:"*Static"})," types"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Before"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-tsx",metastring:'title=""',children:"import {Linking, LinkingStatic} from 'react-native';\n\nfunction foo(linking: LinkingStatic) {}\nfoo(Linking);\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"After"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-tsx",metastring:'title=""',children:"import {Linking} from 'react-native';\n\nfunction foo(linking: Linking) {}\nfoo(Linking);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The following APIs were previously named as ",(0,s.jsx)(n.code,{children:"*Static"})," plus a variable declaration of said type. In most cases there was an alias so that value and the type were exported under the same identifier, but some were missing."]}),"\n",(0,s.jsxs)(n.p,{children:["(For example there was an ",(0,s.jsx)(n.code,{children:"AlertStatic"})," type, ",(0,s.jsx)(n.code,{children:"Alert"})," variable of type ",(0,s.jsx)(n.code,{children:"AlertStatic"})," and type ",(0,s.jsx)(n.code,{children:"Alert"})," which was an alias for ",(0,s.jsx)(n.code,{children:"AlertStatic"}),". But in the case of ",(0,s.jsx)(n.code,{children:"PixelRatio"})," there was a ",(0,s.jsx)(n.code,{children:"PixelRatioStatic"})," type and a ",(0,s.jsx)(n.code,{children:"PixelRatio"})," variable of that type without additional type aliases.)"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Affected APIs"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"AlertStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ActionSheetIOSStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ToastAndroidStatic"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"InteractionManagerStatic"})," (In this case there was no relevant ",(0,s.jsx)(n.code,{children:"InteractionManager"})," type alias)"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"UIManagerStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"PlatformStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"SectionListStatic"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PixelRatioStatic"})," (In this case there was no relevant ",(0,s.jsx)(n.code,{children:"PixelRatio"})," type alias)"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"AppStateStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"AccessibilityInfoStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ImageResizeModeStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"BackHandlerStatic"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"DevMenuStatic"})," (In this case there was no relevant ",(0,s.jsx)(n.code,{children:"DevMenu"}
1)," type alias)"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ClipboardStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"PermissionsAndroidStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ShareStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"DeviceEventEmitterStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"LayoutAnimationStatic"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"KeyboardStatic"})," (In this case there was no relevant ",(0,s.jsx)(n.code,{children:"Keyboard"})," type alias)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"DevSettingsStatic"})," (In this case there was no relevant ",(0,s.jsx)(n.code,{children:"DevSettings"})," type alias)"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"I18nManagerStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"EasingStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"PanResponderStatic"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NativeModulesStatic"})," (In this case there was no relevant ",(0,s.jsx)(n.code,{children:"NativeModules"})," type alias)"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"LogBoxStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"PushNotificationIOSStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"SettingsStatic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"VibrationStatic"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"some-core-components-are-now-function-components-instead-of-class-components",children:"Some core components are now function components instead of class components"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"View"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"Image"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"TextInput"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"Modal"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"Text"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"TouchableWithoutFeedback"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"Switch"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ActivityIndicator"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"ProgressBarAndroid"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"InputAccessoryView"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"Button"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"SafeAreaView"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Due to this change, accessing ref types of these views requires using ",(0,s.jsx)(n.code,{children:"React.ComponentRef<typeof View>"})," pattern which works as expected for both class and function components, e.g.:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'title=""',children:"const ref = useRef<React.ComponentRef<typeof View>>(null);\n"})}),"\n",(0,s.jsx)(n.h2,{id:"other-breaking-changes",children:"Other breaking changes"}),"\n",(0,s.jsx)(n.h3,{id:"changes-to-animated-types",children:"Changes to Animated types"}),"\n",(0,s.jsxs)(n.p,{children:["Animated nodes were previously generic types based on their interpolation output. Now, they are non-generic types with a generic ",(0,s.jsx)(n.code,{children:"interpolate"})," method."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Animated.LegacyRef"})," is no longer available."]}),"\n",(0,s.jsx)(n.h3,{id:"unified-types-for-optional-props",children:"Unified types for optional props"}),"\n",(0,s.jsxs)(n.p,{children:["In the new types, every optional prop will be typed as ",(0,s.jsx)(n.code,{children:"type | undefined"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"removal-of-some-deprecated-types",children:"Removal of some deprecated types"}),"\n",(0,s.jsxs)(n.p,{children:["All types listed in ",(0,s.jsx)(o.A,{href:"/packages/react-native/types/public/DeprecatedPropertiesAlias.d.ts",children:(0,s.jsx)(n.code,{children:"DeprecatedPropertiesAlias.d.ts"})})," are inaccessible under the Strict API."]}),"\n",(0,s.jsx)(n.h3,{id:"removal-of-leftover-component-props",children:"Removal of leftover component props"}),"\n",(0,s.jsxs)(n.p,{children:["Some properties that were defined in type definitions but were not used by the component or were lacking a definition were removed (for example: ",(0,s.jsx)(n.code,{children:"lineBreakMode"})," on ",(0,s.jsx)(n.code,{children:"Text"}),", ",(0,s.jsx)(n.code,{children:"scrollWithoutAnimationTo"})," on ",(0,s.jsx)(n.code,{children:"ScrollView"}),", transform styles defined outside of transform array)."]}),"\n",(0,s.jsx)(n.h3,{id:"previously-accessible-private-type-helpers-may-now-be-removed",children:"Previously accessible private type helpers may now be removed"}),"\n",(0,s.jsxs)(n.p,{children:["Due to the configuration of the previous type definitions, every defined type was accessible from the ",(0,s.jsx)(n.code,{children:"react-native"})," package. This included types that were not explicitly exported and helper types that were only supposed to be used internally."]}),"\n",(0,s.jsxs)(n.p,{children:["Notable examples of this are types related to StyleSheet (like ",(0,s.jsx)(n.code,{children:"RecursiveArray"}),", ",(0,s.jsx)(n.code,{children:"RegisteredStyle"})," and ",(0,s.jsx)(n.code,{children:"Falsy"}),") and Animated (like ",(0,s.jsx)(n.code,{children:"WithAnimatedArray"})," and ",(0,s.jsx)(n.code,{children:"WithAnimatedObject"}),")."]})]})}function p(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},14395(e,n,i){i.d(n,{A:()=>c});var t=i(62540);i(63696);var s=i(11750),r=i(12212),o=i(11535);function c(e){let n=(0,o.v)(e.id);return(0,t.jsx)(r.A,{...e,className:(0,s.A)(n,e.className)})}},9384(e,n,i){i.d(n,{A:()=>o});var t=i(62540),s=i(14395),r=i(93698);function o({href:e,children:n,...i}){return(0,t.jsx)(s.A,{href:`https://github.com/facebook/react-native/blob/${(0,r.M)()}/${e.startsWith("/")?e.slice(1):e}`,...i,children:n})}},93698(e,n,i){i.d(n,{M:()=>s});var t=i(94540);function s(){let e=(0,t.ir)(void 0);return"Next"===e.label?"main":`${e.label}-stable`}},43023(e,n,i){i.d(n,{R:()=>o,x:()=>c});var t=i(63696);let s={},r=t.createContext(s);function o(e){let n=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.