You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.d.ts文件中导入.ts文件中的类型(Electron场景)

解决Electron preload.d.ts导入共享类型后window.api变为any的问题

问题根源

当preload.d.ts中使用import导入外部类型时,该文件会从全局声明文件转为模块文件,此时直接扩展Window接口不会被TypeScript识别为全局扩展,导致window.api被推断为any。

解决方案

1. 使用declare global包裹全局接口扩展

在preload.d.ts中,导入类型后通过declare global块来扩展Window接口,同时添加空导出确保文件被识别为模块:

// preload.d.ts
import type { IpcChannels } from '@shared/channelNames';

declare global {
  interface Window {
    api: {
      // 根据你的IpcChannels定义调整具体方法类型
      invoke: <T extends keyof IpcChannels>(
        channel: T,
        ...args: Parameters<IpcChannels[T]['invoke']>
      ) => Promise<ReturnType<IpcChannels[T]['invoke']>>;
      // 其他需要暴露的API方法...
    };
  }
}

// 必须添加此导出,标记文件为模块
export {};

2. 确保渲染进程tsconfig的路径解析正确

检查渲染进程的tsconfig.json,确认baseUrl和paths配置能正确解析@shared别名,同时包含preload.d.ts:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@shared/*": ["shared/*"]
    },
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Node",
    // 其他编译配置...
  },
  "include": [
    "render/**/*",
    "preload/preload.d.ts"
  ]
}

3. 保持preload.ts与声明文件类型一致

确保preload.ts中通过contextBridge暴露的API类型与preload.d.ts定义完全匹配:

// preload.ts
import { contextBridge, ipcRenderer } from 'electron';
import type { IpcChannels } from '@shared/channelNames';

contextBridge.exposeInMainWorld('api', {
  invoke: async <T extends keyof IpcChannels>(channel: T, ...args: Parameters<IpcChannels[T]['invoke']>) => {
    return ipcRenderer.invoke(channel, ...args) as Promise<ReturnType<IpcChannels[T]['invoke']>>;
  }
});

这样就能不用复制类型定义,直接导入IpcChannels并正确为window.api提供类型提示。

内容的提问来源于stack exchange,提问作者GuangWu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:36:25