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

如何集中为非JS文件(如SQL)声明TypeScript类型?

集中式为SQL文件配置TypeScript类型声明

针对你开发Vite插件加载.sql文件时的类型声明需求,这里提供一种集中式管理且支持不同SQL文件自定义返回类型的方案:

方案概述

通过基础模块声明+集中类型映射+可选自动生成脚本的组合,既满足每个SQL文件的专属类型需求,又避免分散的.d.ts文件,实现类型集中管理。

1. 基础模块声明

在项目的types目录下创建sql.d.ts,让TypeScript识别所有.sql模块:

// types/sql.d.ts
declare module "*.sql" {
  // 定义SQL导出的基础结构,根据你的插件实际输出调整
  type BaseSqlQuery<T = unknown> = {
    sql: string;
    // 示例:假设你的插件提供执行方法,返回Promise<T>
    execute(): Promise<T>;
  };
  const query: BaseSqlQuery;
  export default query;
}

2. 集中维护类型映射

在types目录下创建sql-types.ts,统一管理所有SQL文件的返回类型映射:

// types/sql-types.ts
// 1. 定义各个SQL查询的返回类型(可关联项目中已有的DTO/接口)
export type UserListResult = {
  id: number;
  username: string;
  email: string;
};

export type OrderStatsResult = {
  totalOrders: number;
  pendingOrders: number;
};

// 2. 创建文件路径到返回类型的映射
export interface SqlTypeMap {
  "./src/sql/get-user-list.sql": UserListResult;
  "./src/sql/get-order-stats.sql": OrderStatsResult;
  // 按实际SQL文件路径逐一添加
}

3. 类型关联与自动推断

为了让TypeScript自动识别每个SQL文件的专属类型,你可以选择以下两种方式:

方式A:使用类型助手函数(推荐)

在项目工具目录创建sql-utils.ts,封装导入逻辑并绑定类型:

// src/utils/sql-utils.ts
import type { SqlTypeMap } from "../../types/sql-types";

// 导入SQL文件时自动匹配对应类型
export function loadSql<T extends keyof SqlTypeMap>(filePath: T) {
  return require(filePath).default as {
    sql: string;
    execute(): Promise<SqlTypeMap[T]>;
  };
}

使用示例:

// 业务代码中导入SQL
import { loadSql } from "./utils/sql-utils";

const userListQuery = loadSql("./src/sql/get-user-list.sql");
// userListQuery.execute() 的返回类型自动推断为 UserListResult

方式B:扩展模块声明(进阶)

修改sql.d.ts,利用TypeScript的模块扩展能力关联类型映射:

// types/sql.d.ts
import type { SqlTypeMap } from "./sql-types";

declare module "*.sql" {
  type BaseSqlQuery<T = unknown> = {
    sql: string;
    execute(): Promise<T>;
  };

  // 从导入路径匹配映射中的类型
  type CurrentPath = `${string}.sql`;
  type QueryResult = CurrentPath extends keyof SqlTypeMap
    ? SqlTypeMap[CurrentPath]
    : unknown;

  const query: BaseSqlQuery<QueryResult>;
  export default query;
}

这种方式无需额外工具函数,直接导入SQL文件即可自动匹配类型(需确保路径完全匹配SqlTypeMap中的键)。

4. 可选:自动生成类型映射脚本

如果SQL文件较多,手动维护SqlTypeMap麻烦,可以写一个Node脚本自动生成:

// scripts/generate-sql-types.js
const fs = require("fs");
const path = require("path");

const sqlRootDir = path.resolve(__dirname, "../src/sql");
const outputFile = path.resolve(__dirname, "../types/sql-types.ts");

// 遍历所有SQL文件
const sqlFiles = fs.readdirSync(sqlRootDir, { recursive: true })
  .filter(file => file.endsWith(".sql"))
  .map(file => path.join("./src/sql", file));

// 生成类型映射内容
let typeContent = `// 自动生成,请勿手动修改
// 如需自定义返回类型,请修改下方对应的接口定义

`;

// 为每个SQL文件生成默认类型(可根据实际需求扩展,比如从SQL注释提取类型)
sqlFiles.forEach(filePath => {
  const typeName = filePath.replace(/\.\/src\/sql\/|\.sql/g, "").replace(/[-/]/g, "") + "Result";
  typeContent += `export type ${typeName} = unknown;\n`;
});

typeContent += `\nexport interface SqlTypeMap {\n`;
sqlFiles.forEach(filePath => {
  const typeName = filePath.replace(/\.\/src\/sql\/|\.sql/g, "").replace(/[-/]/g, "") + "Result";
  typeContent += `  "${filePath}": ${typeName};\n`;
});
typeContent += `}\n`;

// 写入文件
fs.writeFileSync(outputFile, typeContent);

运行脚本后,sql-types.ts会自动生成所有SQL文件的类型映射,你只需修改其中的unknown为实际返回类型即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:13:27