提问人:Ruri 提问时间:11/16/2023 最后编辑:Ruri 更新时间:11/16/2023 访问量:42
如何为我的 JavaScript 模块添加类型?
How do I add typings for my JavaScript module?
问:
这绝对是重复的,但我很难弄清楚如何将d.ts等类型添加到我的库/模块中。
我尝试编辑我的并添加,但它似乎不起作用,所以也许我只是做错了。package.json
"types": "./typings/index.d.ts"
它还使用一个旧库,我将其用作 API,而这个模块只是它的客户端包装器。
引用:
// index.d.ts
export class Message {
constructor(client: any, message: any)
attachments: any[];
body: string;
isGroup: boolean;
mentions: { [id: string]: string };
messageID: string;
senderID: string;
threadID: string;
isUnread: boolean;
type: 'message';
}
// Message.js
class Message {
constructor(_client, event) {
for (const key in event) {
if (event.hasOwnProperty(key)) {
this[key] = event[key];
}
}
}
}
module.exports = Message;
// MessageCreate.js (Event handler)
const Message = require('../../structures/Message');
module.exports = (client, event) => {
const message = new Message(client, event);
client.emit('messageCreate', message);
}
// index.js (main script)
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) => { // Here, I want to add a type for message
console.log(message);
})
client.login(appState);
// Client.js
const login = require("../lib/index");
const { EventEmitter } = require('events');
const Events = require('./Event.js');
class MessengerClient extends EventEmitter {
constructor(options = {}) {
super();
this.api = null;
this.options = options;
this.user = null;
}
async login(appState) {
try {
const api = await new Promise((resolve, reject) => {
login(appState, (err, api) => {
if (err) {
reject(err);
} else {
resolve(api);
}
});
});
this.api = api;
const clientID = api.getCurrentUserID();
const clientUser = await api.getUserInfo(clientID);
this.user = clientUser[clientID];
new Events(this);
} catch (error) {
console.error('Error during login:', error);
}
}
}
module.exports = MessengerClient;
答:
0赞
Jared Smith
11/16/2023
#1
您需要为 MessageClient 类编写声明,并为该方法添加重载签名。我通常只写打字稿,而不是手动写声明文件,但它应该看起来像这样:on
export class MessageClient {
api: null | whatever; // replace with real type
options: null | whatever; // replace with real type
user: null | whatever; // replace with real type
login(state: whatever): Promise<void>; // replace with real type
on(evtType: 'messageCreate', cb: (msg: Message) => void): void
on(evtType: string, cb: (result?: any) => void): void // you may want unknown here instead of any
}
请注意,重载通常应从上到下更具体到更不具体。
我不得不这样说:我意识到你可能没有责任,你可能无法改变它,但代码设计得很糟糕。如果类在构造时具有一堆 null 属性,这些属性在将来的某个时间点被初始化,则是一种 OO 反模式。
如果此类需要登录信息才能正确实例化,则不应是该类的方法。将它拉出到函数中,并在拥有它后才实例化 MessengerClient,然后删除所有 s。login
| null
使用构造函数来产生副作用(例如没有分配给任何东西)也是另一种 OO 反模式。没有看到足够的代码来为您提供不同的建议,但这是一个很常见的问题,Javascript linter 有禁止这样做的规则(您在这个项目中使用了 linter......对吧?new Events(this);
评论
0赞
Ruri
11/16/2023
这样做了,它仍然不起作用(每当我将鼠标悬停在消息上时,它仍然any
)
0赞
Jared Smith
11/16/2023
@Ruri 1.只有当事件类型是编译时常量(如字符串文本)时,它才会起作用(并且只能起作用)。2. 你是怎么检查的?这应该有效,所以我会通过将 (result?: any) 更改为 (result: number) 来测试测试,并查看 IDE 中的工具提示是否更改。
评论