严格的 TypeScript API(选择启用)
严格的 TypeScript API 是我们 React Native 未来稳定 JavaScript API 的预览版。
具体来说,这是一套新的 TypeScript 类型,适用于 react-native
npm 包,从 0.80 版本开始提供。它们提供了更强、更具未来保障的类型准确性,并将使我们能够自信地将 React Native 的 API 发展为稳定的形态。选择加入严格的 TypeScript API 会带来一些结构上的类型差异,因此这是一次性破坏性更改。
新类型是
- 直接从我们的源代码生成 — 提高覆盖率和正确性,因此您可以期待更强的兼容性保证。
- 限于
react-native
的索引文件 — 更严格地定义了我们的公共 API,这意味着在进行内部文件更改时,我们不会破坏 API。
当社区准备就绪时,严格的 TypeScript API 将在未来成为我们的默认 API — 与深度导入的移除同步。
选择加入
我们正在与现有类型一同发布这些新类型,这意味着您可以选择在准备好时进行迁移。我们鼓励早期采用者和新创建的应用程序通过 tsconfig.json
文件选择加入。
选择加入是一个破坏性更改,因为我们的一些新类型已更新名称和形状,尽管许多应用程序不会受到影响。您可以在下一节中了解每个破坏性更改。
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
...
"customConditions": ["react-native-strict-api"]
}
}
这将指示 TypeScript 从我们新的 types_generated/
目录(而不是之前手动维护的 types/
目录)解析 react-native
类型。不需要重启 TypeScript 或您的编辑器。
严格的 TypeScript API 遵循我们 RFC 中关于移除 React Native 深度导入的提议。因此,一些 API 不再在根目录下导出。这是有意为之,目的是减少 React Native API 的整体表面积。
迁移指南
Codegen 类型现在应从 react-native
包导入
用于 codegen 的类型,如 Int32
、Double
、WithDefault
等,现在可在单个 CodegenTypes
命名空间下使用。同样,codegenNativeComponent
和 codegenNativeCommands
现在可从 react-native 包导入,而不是使用深度导入。
当未启用严格 API 时,命名空间 CodegenTypes
以及 codegenNativeCommands
和 codegenNativeComponent
也可从 react-native
包获得,以便第三方库更容易采用。
之前
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type {
Int32,
WithDefault,
} from 'react-native/Libraries/Types/CodegenTypes';
interface NativeProps extends ViewProps {
enabled?: WithDefault<boolean, true>;
size?: Int32;
}
export default codegenNativeComponent<NativeProps>(
'RNCustomComponent',
);
之后
import {CodegenTypes, codegenNativeComponent} from 'react-native';
interface NativeProps extends ViewProps {
enabled?: CodegenTypes.WithDefault<boolean, true>;
size?: CodegenTypes.Int32;
}
export default codegenNativeComponent<NativeProps>(
'RNCustomComponent',
);
移除 *Static
类型
之前
import {Linking, LinkingStatic} from 'react-native';
function foo(linking: LinkingStatic) {}
foo(Linking);
之后
import {Linking} from 'react-native';
function foo(linking: Linking) {}
foo(Linking);
以下 API 之前被命名为 *Static
加上该类型的变量声明。在大多数情况下,存在别名,以便值和类型在同一个标识符下导出,但有些缺失。
(例如,有一个 AlertStatic
类型,一个 Alert
变量,类型为 AlertStatic
,以及一个 Alert
类型,它是 AlertStatic
的别名。但在 PixelRatio
的情况下,有一个 PixelRatioStatic
类型和一个该类型的 PixelRatio
变量,没有额外的类型别名。)
受影响的 API
AlertStatic
ActionSheetIOSStatic
ToastAndroidStatic
InteractionManagerStatic
(在这种情况下,没有相关的InteractionManager
类型别名)UIManagerStatic
PlatformStatic
SectionListStatic
PixelRatioStatic
(在这种情况下,没有相关的PixelRatio
类型别名)AppStateStatic
AccessibilityInfoStatic
ImageResizeModeStatic
BackHandlerStatic
DevMenuStatic
(在这种情况下,没有相关的DevMenu
类型别名)ClipboardStatic
PermissionsAndroidStatic
ShareStatic
DeviceEventEmitterStatic
LayoutAnimationStatic
KeyboardStatic
(在这种情况下,没有相关的Keyboard
类型别名)DevSettingsStatic
(在这种情况下,没有相关的DevSettings
类型别名)I18nManagerStatic
EasingStatic
PanResponderStatic
NativeModulesStatic
(在这种情况下,没有相关的NativeModules
类型别名)LogBoxStatic
PushNotificationIOSStatic
SettingsStatic
VibrationStatic
一些核心组件现在是函数组件而不是类组件
View
Image
TextInput
Modal
Text
TouchableWithoutFeedback
Switch
ActivityIndicator
ProgressBarAndroid
InputAccessoryView
Button
SafeAreaView
由于此更改,访问这些视图的 ref 类型需要使用 React.ComponentRef<typeof View>
模式,该模式对类组件和函数组件都按预期工作,例如
const ref = useRef<React.ComponentRef<typeof View>>(null);
其他破坏性更改
Animated 类型的更改
Animated 节点以前是基于其插值输出的泛型类型。现在,它们是非泛型类型,带有一个泛型 interpolate
方法。
Animated.LegacyRef
不再可用。
可选属性的统一类型
在新类型中,每个可选属性都将被类型化为 type | undefined
。
移除一些已弃用的类型
DeprecatedPropertiesAlias.d.ts
中列出的所有类型在严格 API 下都无法访问。
移除剩余的组件属性
一些在类型定义中定义但组件未使用或缺少定义的属性已被移除(例如:Text
上的 lineBreakMode
,ScrollView
上的 scrollWithoutAnimationTo
,在 transform 数组外部定义的 transform 样式)。
以前可访问的私有类型助手现在可能已被移除
由于以前类型定义的配置,每个定义的类型都可以从 react-native
包中访问。这包括未明确导出的类型和仅供内部使用的辅助类型。
这方面值得注意的例子是与 StyleSheet 相关的类型(如 RecursiveArray
、RegisteredStyle
和 Falsy
)和 Animated 相关的类型(如 WithAnimatedArray
和 WithAnimatedObject
)。