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

如何为JavaScript模块添加d.ts类型定义?

给CommonJS风格的Node.js库添TypeScript类型定义

1. 修正类型定义的导出匹配

你的Message类用CommonJS导出(module.exports = Message),原.d.ts的ES模块导出方式不匹配,得改成对应格式。

如果是要发布的库,修改typings/index.d.ts:

// typings/index.d.ts
declare module '你的库名' { // 替换成package.json里的name字段值,比如"messenger-client"
  import { EventEmitter } from 'events';

  export class Message {
    constructor(client: MessengerClient, message: any);
    attachments: any[];
    body: string;
    isGroup: boolean;
    mentions: { [id: string]: string };
    messageID: string;
    senderID: string;
    threadID: string;
    isUnread: boolean;
    type: 'message';
  }

  export class MessengerClient extends EventEmitter {
    constructor(options?: Record<string, any>);
    api: any; // 后续可以根据API文档细化这个类型
    options: Record<string, any>;
    user: { name: string } & Record<string, any>;
    login(appState: any): Promise<void>;

    // 给EventEmitter扩展事件类型,让on方法能识别参数类型
    on(event: 'ready', listener: (client: MessengerClient) => void): this;
    on(event: 'messageCreate', listener: (message: Message) => void): this;
    on(event: string, listener: (...args: any[]) => void): this;
  }
}

如果是本地项目自用,不用declare module,直接给JS文件加类型声明:

// typings/index.d.ts
import { EventEmitter } from 'events';

export class Message {
  constructor(client: MessengerClient, message: any);
  attachments: any[];
  body: string;
  isGroup: boolean;
  mentions: { [id: string]: string };
  messageID: string;
  senderID: string;
  threadID: string;
  isUnread: boolean;
  type: 'message';
}

export class MessengerClient extends EventEmitter {
  constructor(options?: Record<string, any>);
  api: any;
  options: Record<string, any>;
  user: { name: string } & Record<string, any>;
  login(appState: any): Promise<void>;

  on(event: 'ready', listener: (client: MessengerClient) => void): this;
  on(event: 'messageCreate', listener: (message: Message) => void): this;
  on(event: string, listener: (...args: any[]) => void): this;
}

// 给Client.js绑定类型
declare module '../src/client/Client' {
  export = MessengerClient;
}

// 给Message.js绑定类型
declare module '../src/structures/Message' {
  export = Message;
}

2. 配置package.json与TypeScript

  • 确保package.json里的types字段指向正确路径:
{
  "name": "你的库名",
  "main": "./index.js",
  "types": "./typings/index.d.ts"
}
  • 如果是本地项目,在tsconfig.json里添加类型文件扫描:
{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES6",
    "strict": true
  },
  "include": ["src/**/*", "typings/**/*"]
}

3. 在主文件中启用类型提示

方案1:改用TypeScript文件(index.ts)

import { MessengerClient, Message } from './typings/index'; // 或直接import你的库名

const appState = require('./appState.json');
const client = new MessengerClient();

client.on('ready', (client) => {
  console.log(`Logged in as '${client.user.name}'`);
});

client.on('messageCreate', (message: Message) => {
  console.log(message.body); // 现在能自动补全属性
});

client.login(appState);

方案2:保留JavaScript,开启类型检查

在index.js顶部加注释,让VSCode识别类型:

// @ts-check
/// <reference path="./typings/index.d.ts" />

const MessengerClient = require("./src/client/Client");

const appState = require('./appState.json');
const client = new MessengerClient();

client.on('ready', (client) => {
  console.log(`Logged in as '${client.user.name}'`);
});

client.on('messageCreate', (message) => {
  console.log(message.body); // 自动识别message类型
});

client.login(appState);

4. 排查不生效的情况

如果还是没提示,检查这几点:

  • package.json的types路径是否写错,比如有没有漏写typings/前缀
  • 类型定义里的属性名和JS文件完全一致(比如JS里是messageID,d.ts里不能写成messageId)
  • tsconfig.json的include有没有包含typings目录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:10:16