📝
jsdoc + ts-check 環境でdiscord.jsのGuildMemberをMockする
かなりニッチであることは自覚しています、、、
出来るなら素直にTypescriptで書いた方が速いのでは?と思いますが、jsdoc + ts-checkという環境で開発してみたかったんです。
環境
前提
discord.jsはつくりとしてはEasy寄りだと感じています。API呼び出しとかめちゃくちゃラップされてるし、サジェスト見ながら適当に書いてもまあまあ書ける感じです。
そういうことで自分で定義している関数の引数にもDiscord.jsのオブジェクトをそのまま使っています。
例
/**
* @param {import('discord.js').GuildMember} member
* @returns string
*/
export const getDisplayName = (member) => {
return member.nickname || member.user.username
}
課題
テストコードを書こうとするとGuildMemberの生成が難儀。
// @ts-check
import { test } from 'vitest';
import { GuildMember} from 'discord.js';
import { getDisplayName } from './get-display-name.js';
test(getDisplayName, () => {
// これはエラー
// Constructor of class 'GuildMember' is private and only accessible within the class declaration.ts(2673)
// const actual = getDisplayName(new GuildMember);
// これはエラー
// Type '{}' is missing the following properties from type 'GuildMember': _roles, avatar, bannable, dmChannel, and 40 more.ts(2740)
// const actual = getDisplayName({ nickname: 'user1' });
// これはエラー
// Argument of type '{ nickname: string; }' is not assignable to parameter of type 'Partial<GuildMember>'.
// The types returned by 'toString()' are incompatible between these types.
// Type 'string' is not assignable to type '`<@${string}>`'.ts(2345)
// const actual = getDisplayName(makeGuildMember({ nickname: 'user1' }));
// これは通るが、補完が効かないのでやりたくない
const actual = getDisplayName(makeGuildMember2({ nickname: 'user1' }));
});
/**
* @param {Partial<import('discord.js').GuildMember>} member
* @returns {import('discord.js').GuildMember}
*/
const makeGuildMember = (member) => {
// @ts-expect-error
return member;
};
/**
* @param {any} member
* @returns {import('discord.js').GuildMember}
*/
const makeGuildMember2 = (member) => {
return member;
};
暫定対応
とりあえずPickしている
/**
* @param {Pick<Partial<import('discord.js').GuildMember>, 'nickname'>} member
* @returns {import('discord.js').GuildMember}
*/
const makeGuildMember = (member) => {
// @ts-expect-error
return member;
};
後で試したい
- vitestのmockでどうにかする
参考
- jsdocでのasみたいな
Discussion