Skip to content

TypeScript compiler cannot find ReferrerPolicy & RequestDestination in node_modules/@types/react-dom #62044

Open
@ariaydejawad

Description

@ariaydejawad

🔎 Search Terms

"TS2304", "ReferrerPolicy", "React", "react-dom', and "RequestDestination"

🕗 Version & Regression Information

Key version information: This bug is reproducible on tsc Version 5.8.3.

Notes: Trying older versions of the TypeScript compiler leads to different errors, mainly with using features in my configuration file for TypeScript that are not supported by older versions. Thus, I could not reproduce this bug on older versions of the compiler, like Version 5.5.4.

💻 Code

My demonstration code is here:

import {useState} from "react";

function App() {
	const [consent, setConsent] = useState(null);
	const [consentReprompter, setConsentReprompter] = useState(null);

My configuration files for TypeScript are here:

tsconfig.json:

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}

tsconfig.app.json:

{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2022",
    "useDefineForClassFields": true,
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": false,

    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,

    "pretty": false
  },

  "include": ["src"]
}

tsconfig.node.json:

{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "target": "ES2023",
    "lib": ["ES2023"],
    "module": "ESNext",
    "skipLibCheck": false,

    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "moduleDetection": "force",
    "noEmit": true,

    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,

    "pretty": false
  },
  "include": ["vite.config.ts"]
}

My error message is here:

ajawad@Macintosh frontend > npm run build

> frontend@0.0.0 build
> tsc -b --pretty false && vite build

node_modules/@types/react-dom/index.d.ts(86,22): error TS2304: Cannot find name 'ReferrerPolicy'.
node_modules/@types/react-dom/index.d.ts(92,31): error TS2304: Cannot find name 'RequestDestination'.

My node_modules/@types/react-dom/index.d.ts file is here:

// NOTE: Users of the `experimental` builds of React should add a reference
// to 'react-dom/experimental' in their project. See experimental.d.ts's top comment
// for reference and documentation on how exactly to do it.

export as namespace ReactDOM;

import { Key, ReactNode, ReactPortal } from "react";

export function createPortal(
    children: ReactNode,
    container: Element | DocumentFragment,
    key?: Key | null,
): ReactPortal;

export const version: string;

export function flushSync<R>(fn: () => R): R;

export function unstable_batchedUpdates<A, R>(callback: (a: A) => R, a: A): R;
export function unstable_batchedUpdates<R>(callback: () => R): R;

export interface FormStatusNotPending {
    pending: false;
    data: null;
    method: null;
    action: null;
}

export interface FormStatusPending {
    pending: true;
    data: FormData;
    method: string;
    action: string | ((formData: FormData) => void | Promise<void>);
}

export type FormStatus = FormStatusPending | FormStatusNotPending;

export function useFormStatus(): FormStatus;

export function useFormState<State>(
    action: (state: Awaited<State>) => State | Promise<State>,
    initialState: Awaited<State>,
    permalink?: string,
): [state: Awaited<State>, dispatch: () => void, isPending: boolean];
export function useFormState<State, Payload>(
    action: (state: Awaited<State>, payload: Payload) => State | Promise<State>,
    initialState: Awaited<State>,
    permalink?: string,
): [state: Awaited<State>, dispatch: (payload: Payload) => void, isPending: boolean];

export function prefetchDNS(href: string): void;

export interface PreconnectOptions {
    // Don't create a helper type.
    // It would have to be in module scope to be inlined in TS tooltips.
    // But then it becomes part of the public API.
    // TODO: Upstream to microsoft/TypeScript-DOM-lib-generator -> w3c/webref
    // since the spec has a notion of a dedicated type: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attribute
    crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
}
export function preconnect(href: string, options?: PreconnectOptions): void;

export type PreloadAs =
    | "audio"
    | "document"
    | "embed"
    | "fetch"
    | "font"
    | "image"
    | "object"
    | "track"
    | "script"
    | "style"
    | "video"
    | "worker";
export interface PreloadOptions {
    as: PreloadAs;
    crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
    fetchPriority?: "high" | "low" | "auto" | undefined;
    // TODO: These should only be allowed with `as: 'image'` but it's not trivial to write tests against the full TS support matrix.
    imageSizes?: string | undefined;
    imageSrcSet?: string | undefined;
    integrity?: string | undefined;
    type?: string | undefined;
    nonce?: string | undefined;
    referrerPolicy?: ReferrerPolicy | undefined;
    media?: string | undefined;
}
export function preload(href: string, options?: PreloadOptions): void;

// https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload
export type PreloadModuleAs = RequestDestination;
export interface PreloadModuleOptions {
    /**
     * @default "script"
     */
    as: PreloadModuleAs;
    crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
    integrity?: string | undefined;
    nonce?: string | undefined;
}
export function preloadModule(href: string, options?: PreloadModuleOptions): void;

export type PreinitAs = "script" | "style";
export interface PreinitOptions {
    as: PreinitAs;
    crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
    fetchPriority?: "high" | "low" | "auto" | undefined;
    precedence?: string | undefined;
    integrity?: string | undefined;
    nonce?: string | undefined;
}
export function preinit(href: string, options?: PreinitOptions): void;

// Will be expanded to include all of https://github.com/tc39/proposal-import-attributes
export type PreinitModuleAs = "script";
export interface PreinitModuleOptions {
    /**
     * @default "script"
     */
    as?: PreinitModuleAs;
    crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
    integrity?: string | undefined;
    nonce?: string | undefined;
}
export function preinitModule(href: string, options?: PreinitModuleOptions): void;

export function requestFormReset(form: HTMLFormElement): void;

Here are the npm packages I have installed for my development environment, as well as their version numbers:

frontend@0.0.0 /Users/jdoe/some-project-path/frontend
├── @eslint/js@9.30.1
├── @types/node@24.0.10
├── @types/react-dom@19.1.6
├── @types/react@19.1.8
├── @vitejs/plugin-react@4.6.0
├── eslint-plugin-react-hooks@5.2.0
├── eslint-plugin-react-refresh@0.4.20
├── eslint@9.30.1
├── globals@16.3.0
├── react-dom@19.1.0
├── react@19.1.0
├── typescript-eslint@8.35.1
├── typescript@5.8.3
└── vite@7.0.1

Here is my package.json file:

{
  "name": "frontend",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b --pretty false && vite build",
    "clean": "tsc --build --clean && rm -rf dist",
    "lint": "eslint .",
    "preview": "vite preview",
    "version": "tsc --version",
    "config": "tsc --showConfig"
  },
  "dependencies": {
    "@types/node": "^24.0.10",
    "react": "^19.1.0",
    "react-dom": "^19.1.0"
  },
  "devDependencies": {
    "@eslint/js": "^9.29.0",
    "@types/react": "^19.1.8",
    "@types/react-dom": "^19.1.6",
    "@vitejs/plugin-react": "^4.5.2",
    "eslint": "^9.29.0",
    "eslint-plugin-react-hooks": "^5.2.0",
    "eslint-plugin-react-refresh": "^0.4.20",
    "globals": "^16.2.0",
    "typescript": "~5.8.3",
    "typescript-eslint": "^8.34.1",
    "vite": "^7.0.0"
  }
}

🙁 Actual behavior

Actual behavior summary: Getting errors about TypeScript not being able to find specific types from the type index of the React DOM package.

What I have tried so far with no success: (1) Reinstalling the React DOM types again using npm install --save @types/react-dom, (2) Checked the version numbers of @types/react-dom online at npm and locally, and they match, (3) Swapping the DOM with dom in my tsconfig.app.json file, (4) and added node to my types in the TypeScript configuration file.

🙂 Expected behavior

The TypeScript compiler should be able to find these missing types from the index of the React DOM types. I believe this because: (1) the React DOM index file exists, (2) my TypeScript configuration files work, and seem to be in order, and (3) I have the node_modules/@types/react-dom package installed correctly on my development environment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions