跳到主要内容

严格的 TypeScript API(选择启用)

严格的 TypeScript API 是我们未来稳定版 React Native JavaScript API 的预览。

具体来说,这是一套适用于 react-native npm 包的新 TypeScript 类型,从 0.80 版本起可用。这些类型提供了更强大、更面向未来的类型准确性,并将使我们能够自信地将 React Native 的 API 演变为稳定的形态。选择启用严格的 TypeScript API 会带来一些结构化的类型差异,因此这是一次性的破坏性变更。

新类型具有以下特点:

  1. 直接从我们的源代码生成 — 提高了覆盖率和正确性,因此您可以期待更强的兼容性保证。
  2. 仅限于 react-native 的 index 文件 — 更严格地定义了我们的公共 API,这意味着在进行内部文件更改时不会破坏 API。

当社区准备就绪时,严格的 TypeScript API 将在未来成为我们的默认 API — 与深度导入的移除同步进行。

选择启用

我们正在与现有类型一起发布这些新类型,这意味着您可以选择在准备好时进行迁移。我们鼓励早期采用者和新创建的应用通过您的 tsconfig.json 文件选择启用。

选择启用是一项破坏性变更,因为我们的一些新类型更新了名称和形状,尽管许多应用不会受到影响。您可以在下一节中了解每个破坏性变更。

tsconfig.json
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
...
"customConditions": ["react-native-strict-api"]
}
}
幕后原理

这将指示 TypeScript 从我们新的 types_generated/ 目录解析 react-native 类型,而不是以前的 types/ 目录(手动维护)。无需重启 TypeScript 或您的编辑器。

严格的 TypeScript API 遵循我们的 RFC,以移除 React Native 中的深度导入。因此,一些 API 不再从根目录导出。这是有意为之的,目的是减少 React Native API 的整体表面积。

API 反馈

发送反馈:我们将在(至少)接下来的两个 React Native 版本中与社区合作,最终确定我们将导出的 API。请在我们的反馈帖中分享您的反馈。

另请参阅我们的公告博客文章,了解有关我们动机和时间表的更多信息。

迁移指南

Codegen 类型现在应从 react-native 包导入

用于 Codegen 的类型,例如 Int32DoubleWithDefault 等,现在可在单个 CodegenTypes 命名空间下使用。类似地,codegenNativeComponentcodegenNativeCommands 现在可以从 react-native 包导入,而不是使用深度导入。

当未启用严格 API 时,带命名空间的 CodegenTypes 以及 codegenNativeCommandscodegenNativeComponent 也可从 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 类型、一个 AlertStatic 类型的 Alert 变量,以及一个作为 AlertStatic 别名的 Alert 类型。但在 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 不再可用。

可选 props 的统一类型

在新类型中,每个可选 prop 都将被类型化为 type | undefined

移除部分已弃用的类型

DeprecatedPropertiesAlias.d.ts 中列出的所有类型在严格 API 下都无法访问。

移除遗留的组件 props

一些在类型定义中定义但组件未使用或缺少定义的属性已被移除(例如:Text 上的 lineBreakModeScrollView 上的 scrollWithoutAnimationTo,以及在 transform 数组之外定义的 transform 样式)。

之前可访问的私有类型辅助工具现在可能已被移除

由于之前的类型定义配置,每个定义的类型都可以从 react-native 包访问。这包括未明确导出的类型以及本应仅供内部使用的辅助类型。

值得注意的例子是与 StyleSheet 相关的类型(如 RecursiveArrayRegisteredStyleFalsy)和与 Animated 相关的类型(如 WithAnimatedArrayWithAnimatedObject)。