如何在React 18 alpha中使用TypeScript

2,072

React 18 alpha已经发布,我们如何用TypeScript来使用它呢?

用TypeScript创建一个React应用程序

让我们用Create React App为自己创建一个React TypeScript应用程序。

yarn create react-app my-app --template typescript

现在把React的版本升级到@next

yarn add react@next react-dom@next

这将使你在package.json 使用React 18的条目。它可能会看起来像这样:

    "react": "^18.0.0-alpha-e6be2d531",
    "react-dom": "^18.0.0-alpha-e6be2d531",

如果运行yarn start ,就会发现自己在运行一个React 18应用程序。

使用新的API

因此,尝试使用 [ReactDOM.createRoot](https://github.com/reactwg/react-18/discussions/5)API。正是这个API使我们的应用程序可以使用React 18的新功能。我们将打开index.tsx ,并进行这一改变:

-ReactDOM.render(
-  <React.StrictMode>
-    <App />
-  </React.StrictMode>,
-  document.getElementById('root')
-);

如果单独运行JavaScript,到这就可以了。然而,由于我们也在使用TypeScript,现在就遇到了一个错误。

Property 'createRoot' does not exist on type 'typeof import("/code/my-app/node_modules/@types/react-dom/index")'. TS2339

TypeScript Throws an Error for the createRoot Property

这是TypeScript编译器不了解ReactDOM.createRoot 。这是因为目前我们的应用程序中的类型定义没有定义该API。

所以升级我们的类型定义。

yarn add @types/react @types/react-dom

可惜同样的错误又出现了。

告诉TypeScript关于新的API的信息

如果看一下为API添加支持的PR,我们会发现一些提示。从next.d.ts发现这个信息。

/**
 * These are types for things that are present in the upcoming React 18 release.
 *
 * Once React 18 is released they can just be moved to the main index file.
 *
 * To load the types declared here in an actual project, there are three ways. The easiest one,
 * if your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section,
 * is to add `"react/next"` to the `"types"` array.
 *
 * Alternatively, a specific import syntax can to be used from a typescript file.
 * This module does not exist in reality, which is why the {} is important:
 *
 * ```ts
 * import {} from 'react/next'
 * ```
 *
 * It is also possible to include it through a triple-slash reference:
 *
 * ```ts
 * /// <reference types="react/next" />
 * ```
 *
 * Either the import or the reference only needs to appear once, anywhere in the project.
 */

接下来试试清单上的第一项。编辑我们的tsconfig.json ,在"compilerOptions" 部分添加一个新条目。

    "types": ["react/next", "react-dom/next"]

如果我们用yarn start 重新启动我们的构建,现在会看到一个不同的错误。

Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Document | DocumentFragment | Comment'. Type 'null' is not assignable to type 'Element | Document | DocumentFragment | Comment'. TS2345

TypeScript Throws an Error for the HTMLElement | null Type

这实际上与我们新的React类型定义的问题无关。这是 TypeScript 表示:"我们不能保证document.getElementById('root') 返回的东西不是null 。由于我们是在strictNullChecks 模式下,你需要确定root 不是空的。"

将通过在调用ReactDOM.createRoot 之前测试我们是否有一个元素在发挥作用来处理这个问题。

-const root = ReactDOM.createRoot(document.getElementById('root'));
+const rootElement = document.getElementById('root');
+if (!rootElement) throw new Error('Failed to find the root element');
+const root = ReactDOM.createRoot(rootElement);

随着这一改变,就有了一个使用TypeScript的React 18应用程序。

原文链接:blog.logrocket.com/how-to-use-…