跳到正文
DEV Community· Cihan Koç·· 2 小時前AI 評分56

用小型 TypeScript 檢查找出錯誤的 React 匯入

Catch Invented React Imports with a Small TypeScript Check

AI 導讀

作者示範以小型 TypeScript fixture 檢查 React API 是否從正確套件匯入,並以故意錯誤的匯入確認 TypeScript 會報 TS2724。示例以 React 和 React DOM 19.2.8、TypeScript 5.9.3 測試,並用獨立設定檔只編譯該 fixture。這項檢查只驗證匯入邊界,不能取代應用程式的型別檢查、正式建置及執行時測試。

正文

Trust the types. Check the imports. createPortal maps to react-dom; useState and Fragment map to react.

AI disclosure: OpenAI Codex drafted this tutorial. The examples below were checked by executing TypeScript against the listed installed packages. I maintain Ninna UI; this version uses standard React APIs. The example is a controlled reproduction, not a personal debugging story or a measurement of any agent's error rate.

Cover created with AI-assisted vector code. It maps createPortal to react-dom and useState and Fragment to react.

A generated React feature can contain a familiar API name and still import it from the wrong package. A short TypeScript fixture turns that plausible import into something you can check before accepting the feature.

The useful technique is to check a few dependency boundaries and prove that the check fails for a known wrong import. A passing command alone is weaker evidence if the fixture was never included in the compilation.

Start with a real export boundary

React's documentation imports createPortal from react-dom. This intentionally incorrect fixture imports it from react:

import { createPortal } from "react";
void createPortal;

With the installed versions used here, TypeScript reports TS2724: the react module has no exported member named createPortal. The fix is to use the right public entry point, rather than suppressing the diagnostic or inventing a local module declaration.

Create a tiny audit file

In an existing React/TypeScript project, create react-import-audit.ts:

import { Fragment, useState } from "react";
import { createPortal } from "react-dom";

void [Fragment, useState, createPortal];

The file imports and references values but renders nothing. It does not call a Hook outside a component. The goal is just to resolve the exact exports used by a proposed feature.

If starting with a new project, install the required packages and keep the lockfile:

pnpm add react@latest react-dom@latest
pnpm add -D typescript @types/react @types/react-dom

Give the check a narrow scope

Create tsconfig.react-audit.json beside the fixture:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "types": ["react", "react-dom"],
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true
  },
  "include": ["react-import-audit.ts"]
}

This configuration checks one fixture without pulling in every application route. bundler resolution suits this bundled React example; use your framework's supported configuration for the actual app.

pnpm exec tsc -p tsconfig.react-audit.json

First confirm that the correct fixture compiles. Then deliberately move createPortal into the import from react and remove its react-dom import. Confirm TS2724. Restore the correct imports and confirm success again. That failing control helps verify that the command is compiling the intended file.

noEmit prevents JavaScript output. skipLibCheck skips checking declaration-file internals; it does not skip checking the imports in your source fixture. If the error is a missing dependency instead, inspect installation and the working directory before changing compiler options.

Make it an acceptance condition

An agent instruction can be small and executable:

Before changing a React import:
1. Check the installed package's public exports and current docs.
2. Keep a small fixture for the APIs the feature needs.
3. Prove the fixture catches one known wrong package export.
4. Run the app's normal typecheck and production build.
Do not silence an export error with any, @ts-ignore,
or a fabricated module declaration.

What this result means

The recorded check uses React and React DOM 19.2.8 with TypeScript 5.9.3. The correct fixture produced no diagnostics; the deliberately wrong import produced TS2724. Rerun it after dependency upgrades instead of assuming an old example describes the installed packages.

This checks an import boundary. It does not render a portal, verify the target DOM node, check event propagation, measure a bundle, or establish accessibility. A real feature still needs its normal typecheck, build, runtime tests and interaction checks. Passing declarations also cannot prove that runtime code perfectly matches its published types.

Start with the APIs the feature actually uses. Keep the fixture small, prove it can fail, and keep broader application checks in the acceptance criteria.

Sources

來源:DEV Community · dev.to