如何在.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
相关产品推荐
相关产品推荐

