TypeScript支持 #
一、TypeScript 配置 #
1.1 安装依赖 #
bash
npm install typescript --save-dev
npm install @types/node --save-dev
# 主进程类型
npm install electron --save-dev
# 构建工具
npm install ts-node --save-dev
1.2 tsconfig.json 配置 #
json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": ".",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@electron/*": ["electron/*"]
},
"types": ["node"]
},
"include": [
"src/**/*",
"electron/**/*"
],
"exclude": [
"node_modules",
"dist",
"dist-electron"
]
}
1.3 分离配置 #
json
// tsconfig.node.json (主进程)
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"outDir": "./dist-electron"
},
"include": [
"electron/**/*"
]
}
// tsconfig.web.json (渲染进程)
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"outDir": "./dist"
},
"include": [
"src/**/*"
]
}
二、类型定义 #
2.1 全局类型 #
typescript
// src/types/global.d.ts
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: 'development' | 'production';
ELECTRON_RENDERER_URL?: string;
}
}
2.2 Electron API 类型 #
typescript
// src/types/electron.d.ts
import { IpcRenderer, IpcMain } from 'electron';
interface ElectronAPI {
getAppInfo: () => Promise<AppInfo>;
openFile: () => Promise<string | null>;
saveFile: (content: string) => Promise<boolean>;
onFileChanged: (callback: (data: FileChangeData) => void) => () => void;
}
interface AppInfo {
version: string;
platform: string;
arch: string;
}
interface FileChangeData {
path: string;
type: 'created' | 'modified' | 'deleted';
}
declare global {
interface Window {
electronAPI: ElectronAPI;
}
}
export { ElectronAPI, AppInfo, FileChangeData };
2.3 IPC 通道类型 #
typescript
// electron/types/ipc.ts
export interface IPCChannels {
'app:getInfo': {
request: void;
response: AppInfo;
};
'file:open': {
request: void;
response: string | null;
};
'file:save': {
request: { content: string };
response: boolean;
};
}
export type IPCChannel = keyof IPCChannels;
export type IPCRequest<T extends IPCChannel> = IPCChannels[T]['request'];
export type IPCResponse<T extends IPCChannel> = IPCChannels[T]['response'];
三、类型安全的 IPC #
3.1 主进程处理器 #
typescript
// electron/ipc/handlers.ts
import { ipcMain } from 'electron';
import { IPCChannels, IPCChannel, IPCRequest, IPCResponse } from '../types/ipc';
type IPCHandler<T extends IPCChannel> = (
event: Electron.IpcMainInvokeEvent,
request: IPCRequest<T>
) => Promise<IPCResponse<T>> | IPCResponse<T>;
function registerHandler<T extends IPCChannel>(
channel: T,
handler: IPCHandler<T>
) {
ipcMain.handle(channel, async (event, request) => {
return handler(event, request);
});
}
// 使用
registerHandler('app:getInfo', async () => {
return {
version: app.getVersion(),
platform: process.platform,
arch: process.arch
};
});
registerHandler('file:save', async (event, { content }) => {
// 保存文件
return true;
});
3.2 预加载脚本 #
typescript
// electron/preload.ts
import { contextBridge, ipcRenderer } from 'electron';
import { IPCChannels, IPCChannel, IPCRequest, IPCResponse } from './types/ipc';
async function invoke<T extends IPCChannel>(
channel: T,
request: IPCRequest<T>
): Promise<IPCResponse<T>> {
return ipcRenderer.invoke(channel, request);
}
function on<T extends IPCChannel>(
channel: T,
callback: (response: IPCResponse<T>) => void
): () => void {
const handler = (_event: Electron.IpcRendererEvent, response: IPCResponse<T>) => {
callback(response);
};
ipcRenderer.on(channel, handler);
return () => {
ipcRenderer.removeListener(channel, handler);
};
}
contextBridge.exposeInMainWorld('electronAPI', {
getAppInfo: () => invoke('app:getInfo', undefined as void),
openFile: () => invoke('file:open', undefined as void),
saveFile: (content: string) => invoke('file:save', { content })
});
3.3 渲染进程使用 #
typescript
// src/utils/electron.ts
import { AppInfo } from '@/types/electron';
export async function getAppInfo(): Promise<AppInfo> {
return window.electronAPI.getAppInfo();
}
export async function openFile(): Promise<string | null> {
return window.electronAPI.openFile();
}
export async function saveFile(content: string): Promise<boolean> {
return window.electronAPI.saveFile(content);
}
四、主进程类型 #
4.1 窗口管理类型 #
typescript
// electron/types/window.ts
import { BrowserWindow } from 'electron';
export interface WindowConfig {
name: string;
width: number;
height: number;
minWidth?: number;
minHeight?: number;
resizable?: boolean;
modal?: boolean;
parent?: string;
}
export interface WindowManager {
create(config: WindowConfig): BrowserWindow;
get(name: string): BrowserWindow | undefined;
has(name: string): boolean;
close(name: string): void;
closeAll(): void;
}
4.2 配置类型 #
typescript
// electron/types/config.ts
export interface AppConfig {
app: {
name: string;
version: string;
};
window: {
width: number;
height: number;
x?: number;
y?: number;
isMaximized: boolean;
};
user: {
theme: 'light' | 'dark';
language: string;
};
}
export type PartialAppConfig = PartialDeep<AppConfig>;
interface PartialDeep<T> {
[P in keyof T]?: T[P] extends object ? PartialDeep<T[P]> : T[P];
}
五、渲染进程类型 #
5.1 Vue 组件类型 #
typescript
// src/types/vue.d.ts
import { DefineComponent } from 'vue';
declare module '*.vue' {
const component: DefineComponent<{}, {}, any>;
export default component;
}
5.2 Store 类型 #
typescript
// src/stores/app.ts
import { defineStore } from 'pinia';
interface AppState {
theme: 'light' | 'dark';
sidebarOpen: boolean;
user: User | null;
}
interface User {
id: string;
name: string;
email: string;
}
interface AppActions {
setTheme: (theme: 'light' | 'dark') => void;
toggleSidebar: () => void;
setUser: (user: User | null) => void;
}
export const useAppStore = defineStore<string, AppState, {}, AppActions>('app', {
state: () => ({
theme: 'light',
sidebarOpen: true,
user: null
}),
actions: {
setTheme(theme) {
this.theme = theme;
},
toggleSidebar() {
this.sidebarOpen = !this.sidebarOpen;
},
setUser(user) {
this.user = user;
}
}
});
六、构建配置 #
6.1 Vite 配置 #
typescript
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import electron from 'vite-plugin-electron';
import path from 'path';
export default defineConfig({
plugins: [
vue(),
electron([
{
entry: 'electron/main.ts',
vite: {
build: {
outDir: 'dist-electron',
rollupOptions: {
external: ['electron']
}
}
}
},
{
entry: 'electron/preload.ts',
vite: {
build: {
outDir: 'dist-electron'
}
}
}
])
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
});
6.2 package.json scripts #
json
{
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build && electron-builder",
"typecheck": "vue-tsc --noEmit"
}
}
七、最佳实践 #
7.1 类型检查清单 #
markdown
- [ ] 配置 tsconfig.json
- [ ] 定义全局类型
- [ ] IPC 通道类型化
- [ ] 组件类型定义
- [ ] Store 类型定义
- [ ] 启用严格模式
7.2 类型导入 #
typescript
// 使用 type 关键字导入类型
import type { AppInfo, FileChangeData } from '@/types/electron';
// 或使用类型重导出
export type { AppInfo, FileChangeData } from '@/types/electron';
八、总结 #
8.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 配置分离 | 主进程和渲染进程分离配置 |
| 类型定义 | 全局类型和模块类型 |
| IPC 类型 | 类型安全的进程间通信 |
| 严格模式 | 启用 TypeScript 严格检查 |
8.2 下一步 #
现在你已经掌握了 TypeScript 支持,接下来让我们学习 实战案例,深入了解 Electron 应用的完整开发流程!
最后更新:2026-03-28