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

如何在TypeScript声明文件中用用户传入值作为类型键

解决Prisma扩展的TypeScript声明与参数类型映射问题

一、用泛型实现参数值作为类型键

核心是利用TypeScript的泛型和索引类型捕获用户传入的idFieldName,将其作为其他类型的键。

1. 主声明文件(index.d.ts)

// 定义带泛型的扩展配置接口
interface PrismaExtensionConfig<IdField extends string> {
  idFieldName: IdField;
}

// 基于泛型参数生成目标类型
type IdField<IdField extends string> = { [K in IdField]: string | number };
type IdFieldKey<IdField extends string> = IdField;

// 高阶函数类型定义,避免污染原函数签名
declare function createPrismaExtension<IdField extends string>(
  config: PrismaExtensionConfig<IdField>
): (prisma: Prisma.Client) => Prisma.Client & {
  method_1: (args: MyMethod1Args<IdField>) => Promise<void>;
};

2. 方法声明文件(method_1.d.ts)

import type { IdFieldKey } from './index';

// 用泛型参数约束参数的键
type MyMethod1Args<IdField extends string> = {
  [K in IdFieldKey<IdField>]: string | number;
  otherArg?: string;
};

二、适配高阶函数的JS代码类型

保留JS的高阶函数结构,通过JSDoc补全泛型类型,实现逐步迁移:

/**
 * 创建Prisma扩展
 * @template {string} IdField
 * @param {import('./index').PrismaExtensionConfig<IdField>} config
 * @returns {(prisma: import('@prisma/client').PrismaClient) => import('@prisma/client').PrismaClient & { method_1: (args: import('./method_1').MyMethod1Args<IdField>) => Promise<void> }}
 */
function createPrismaExtension(config) {
  return (prisma) => {
    return {
      ...prisma,
      async method_1(args) {
        // 业务逻辑中直接使用config.idFieldName
        const idValue = args[config.idFieldName];
        // ...
      }
    };
  };
}

module.exports = createPrismaExtension;

三、解决esbuild未检测到的声明文件错误

  • 确保所有声明文件的泛型参数传递一致,避免类型不匹配
  • 在tsconfig.json中配置include字段,覆盖所有.d.ts文件:
{
  "include": ["src/**/*.js", "src/**/*.d.ts"]
}
  • 用tsc --noEmit预先检查声明文件的类型错误,esbuild不做全量类型校验,需手动提前排查

四、逐步迁移策略

  • 先为核心JS文件补全JSDoc泛型,匹配声明文件的类型定义
  • 逐步将复杂逻辑的JS文件重写为TS,替换对应声明文件
  • 保留现有业务代码不动,只在类型层做兼容调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:33:17