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

如何以最小改动将CommonJS模块导入TypeScript项目?

问题:CommonJS gRPC客户端在TypeScript中导入报错

我们有一个基于Twirp的gRPC客户端CommonJS实现,代码如下:

/**
 * Code generated by protoc-gen-twirp_js v5.0.0, DO NOT EDIT.
 * source: domain_service/service.proto
 */
// import our twirp js library dependency
var createClient = require("twirp");
// import our protobuf definitions
var pb = require("./domain_service/service_pb.js");
Object.assign(module.exports, pb);

/**
 * Creates a new DomainClient
 */
module.exports.createDomainClient = function(baseurl, extraHeaders, useJSON) {
    var rpc = createClient(baseurl, "events.domain_service.Domain", "v5.0.0",  useJSON, extraHeaders === undefined ? {} : extraHeaders);
    return {
        fireDomainEvent: function(data) { return rpc("FireDomainEvent", data, pb.FireDomainEventResponse); }
    }
}

我在同一文件夹中创建了对应的d.ts文件:

export function createDomainClient(
  baseurl: any,
  extraHeaders: any,
  useJSON: any
): {
  fireDomainEvent: (data: any) => any;
};

但在TypeScript项目中使用以下代码时:

import { createDomainClient } from '@MyOrganization/package';

const client = new createDomainClient(
  'https://my.url.com', '', false
);

出现错误:

'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.ts(7009)

我希望在对原gRPC仓库改动最小的前提下,解决这个导入问题。


解决方法

1. 修正TypeScript中的调用代码

原JavaScript中的createDomainClient是普通函数,它直接返回客户端对象,不是构造函数,因此不能用new关键字调用。移除new即可解决报错:

import { createDomainClient } from '@MyOrganization/package';

// 移除new关键字
const client = createDomainClient(
  'https://my.url.com', '', false
);

2. 优化d.ts类型定义(可选,提升类型安全性)

原d.ts中使用any过于宽泛,可以根据实际逻辑优化类型,同时匹配原JS的参数默认值逻辑:

// 导入protobuf生成的响应类型(如果有对应的TS定义)
import type { FireDomainEventResponse } from './domain_service/service_pb.js';

export function createDomainClient(
  baseurl: string,
  // extraHeaders设为可选,原JS中默认值为空对象
  extraHeaders?: Record<string, string>,
  // useJSON设为可选,原JS中未指定默认值但可以不传
  useJSON?: boolean
): {
  // 替换data的类型为实际请求参数类型(如果有),返回值设为Promise类型(Twirp客户端默认返回Promise)
  fireDomainEvent: (data: unknown) => Promise<FireDomainEventResponse>;
};

这样改动完全不需要修改原gRPC仓库的JavaScript代码,仅调整TypeScript项目中的调用方式和类型定义即可完成兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:21:49