严格的 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 遵循我们关于从 React Native 中移除深度导入的 RFC。因此,某些 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 类型,一个类型为 AlertStatic 的 Alert 变量,以及一个作为 AlertStatic 别名的 Alert 类型。但在 PixelRatio 的情况下,有一个 PixelRatioStatic 类型和一个该类型的 PixelRatio 变量,没有额外的类型别名。)
受影响的 API
AlertStaticActionSheetIOSStaticToastAndroidStaticInteractionManagerStatic(在此情况下没有相关的InteractionManager类型别名)UIManagerStaticPlatformStaticSectionListStaticPixelRatioStatic(在此情况下没有相关的PixelRatio类型别名)AppStateStaticAccessibilityInfoStaticImageResizeModeStaticBackHandlerStaticDevMenuStatic(在此情况下没有相关的DevMenu类型别名)ClipboardStaticPermissionsAndroidStaticShareStaticDeviceEventEmitterStaticLayoutAnimationStaticKeyboardStatic(在此情况下没有相关的Keyboard类型别名)DevSettingsStatic(在此情况下没有相关的DevSettings类型别名)I18nManagerStaticEasingStaticPanResponderStaticNativeModulesStatic(在此情况下没有相关的NativeModules类型别名)LogBoxStaticPushNotificationIOSStaticSettingsStaticVibrationStatic
某些核心组件现在是函数组件而不是类组件
ViewImageTextInputModalTextTouchableWithoutFeedbackSwitchActivityIndicatorProgressBarAndroidInputAccessoryViewButtonSafeAreaView
由于此更改,访问这些视图的 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)。