Unwrapping `Promise<x>` where `void` expected?

Hi. It's my first time moving to TypeScript from Rust (serenity+poise->discord.js) and I am trying to handle a GuildUpdate event where ownership has been transferred to another. It seems that doing this gives me a Promise<string> which I can't seem to unwrap.
const oldOwnerUsername = await client.users.fetch(oldGuild.ownerId).then(user => user.username);
const oldOwnerUsername = await client.users.fetch(oldGuild.ownerId).then(user => user.username);
When attempting to do so, it asks me to async the part after the event, like so:
client.on(Events.GuildUpdate, async (oldGuild, newGuild) => {
// ..
}
client.on(Events.GuildUpdate, async (oldGuild, newGuild) => {
// ..
}
...but then, it tells me that it expects a void return? In serenity, I just made a function async and handled everything else by calling .await or .await? at the end, depending on whether or not something was a Result<x, y> or not. How exactly am I able to handle the case here?
31 Replies
d.js toolkit
d.js toolkit8mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button! - Marked as resolved by OP
Kawaxte
KawaxteOP8mo ago
1) I use Bun, so bun -version is 1.1.8
xx_lavaboy_xx123
u resolve the promise by using await, u dont need the then if you're using await
Kawaxte
KawaxteOP8mo ago
as i said, it starts complaining that it cannot have async on a void type, because to have an await call, it requires an async declaration.
Unknown User
Unknown User8mo ago
Message Not Public
Sign In & Join Server To View
Kawaxte
KawaxteOP8mo ago
so...it's a double await that i have to double-handle?
Unknown User
Unknown User8mo ago
Message Not Public
Sign In & Join Server To View
Kawaxte
KawaxteOP8mo ago
well, i have the await appended, so I get this issue
xx_lavaboy_xx123
u can just access the username like that (await client.users.fetch(oldGuild.ownerId)).username
Kawaxte
KawaxteOP8mo ago
I do what it asks, and then we get here so exactly what does it want?
Unknown User
Unknown User8mo ago
Message Not Public
Sign In & Join Server To View
Kawaxte
KawaxteOP8mo ago
aaagh this feels extremely weird coming from Rust
duck
duck8mo ago
this sounds more like an issue with how bun handles typescript if you're executing it directly void functions should be able to return anything though that error definitely just looks like a linting error and not a typescript error
Kawaxte
KawaxteOP8mo ago
so it's not a typescript issue? so this function is correct?
export function onGuildUpdate(client: Client) {
client.on(Events.GuildUpdate, async (oldGuild, newGuild) => {
const oldName = oldGuild.name;
const newName = newGuild.name;
if (oldName !== newName) {
console.log(`Renamed '${oldName}' to '${newName}'`);
}

const oldOwnerUsername = await client.users.fetch(oldGuild.ownerId).then(user => user.username);
const newOwnerUsername = await client.users.fetch(newGuild.ownerId).then(user => user.username);
if (oldOwnerUsername !== newOwnerUsername) {
console.log(`'@${oldOwnerUsername}' transferred ownership of '${newName}' to '@${newOwnerUsername}'`);
}
});
}
export function onGuildUpdate(client: Client) {
client.on(Events.GuildUpdate, async (oldGuild, newGuild) => {
const oldName = oldGuild.name;
const newName = newGuild.name;
if (oldName !== newName) {
console.log(`Renamed '${oldName}' to '${newName}'`);
}

const oldOwnerUsername = await client.users.fetch(oldGuild.ownerId).then(user => user.username);
const newOwnerUsername = await client.users.fetch(newGuild.ownerId).then(user => user.username);
if (oldOwnerUsername !== newOwnerUsername) {
console.log(`'@${oldOwnerUsername}' transferred ownership of '${newName}' to '@${newOwnerUsername}'`);
}
});
}
can i... make the function return a Promise so that the warning goes away?
duck
duck8mo ago
async functions always return promises this is also the reason you were receiving the linting error in the first place
Kawaxte
KawaxteOP8mo ago
hmm is that a proper solution though? i'm unclear on whether or not the code itself would be idiomatically correct to a strict TypeScript standard i applied OP's final solution and the warning went away:
export function onGuildUpdate(client: Client) {
client.on(Events.GuildUpdate, (oldGuild, newGuild) => {
void (async () => {
const oldName = oldGuild.name;
const newName = newGuild.name;
if (oldName !== newName) {
console.log(`Renamed '${oldName}' to '${newName}'`);
}

const oldOwnerUsername = await client.users.fetch(oldGuild.ownerId).then(user => user.username);
const newOwnerUsername = await client.users.fetch(newGuild.ownerId).then(user => user.username);
if (oldOwnerUsername !== newOwnerUsername) {
console.log(`'${oldOwnerUsername}' transferred ownership of '${newName}' to '${newOwnerUsername}'`);
}
})();
});
}
export function onGuildUpdate(client: Client) {
client.on(Events.GuildUpdate, (oldGuild, newGuild) => {
void (async () => {
const oldName = oldGuild.name;
const newName = newGuild.name;
if (oldName !== newName) {
console.log(`Renamed '${oldName}' to '${newName}'`);
}

const oldOwnerUsername = await client.users.fetch(oldGuild.ownerId).then(user => user.username);
const newOwnerUsername = await client.users.fetch(newGuild.ownerId).then(user => user.username);
if (oldOwnerUsername !== newOwnerUsername) {
console.log(`'${oldOwnerUsername}' transferred ownership of '${newName}' to '${newOwnerUsername}'`);
}
})();
});
}
looks ugly, but if it works, it's not that stupid
xx_lavaboy_xx123
wouldn't the warning go away if u didnt use then?
Kawaxte
KawaxteOP8mo ago
i have to use then to get the username from user from userId it's almost like the equivalent of using a match statement to unwrap bits and pieces
xx_lavaboy_xx123
u dont need to use then if you're using await const oldOwnerUsername = (await client.users.fetch(oldGuild.ownerId)).username;
Kawaxte
KawaxteOP8mo ago
wait, really? interesting
xx_lavaboy_xx123
await resolves the promise so (await client.users.fetch(oldGuild.ownerId) is of type User
Amgelo
Amgelo8mo ago
what you're awaiting is the .then() since that returns a promise
Kawaxte
KawaxteOP8mo ago
that was a very rustic way of doing it lole it's schtill odd they haven't provided a helper function for returning an owner as User
Amgelo
Amgelo8mo ago
not sure if the warn would go away if you didn't use then though, it seems like the issue is the fact that the callback is async
Kawaxte
KawaxteOP8mo ago
it's not back thanks to the awful workaround from the linked issue solution
d.js docs
d.js docs8mo ago
:method: Guild#fetchOwner @14.15.2 Fetches the owner of the guild. If the member object isn't needed, use ownerId instead.
Kawaxte
KawaxteOP8mo ago
oh?
const oldOwnerUsername = (await oldGuild.fetchOwner()).user.username;
const newOwnerUsername = (await newGuild.fetchOwner()).user.username;
const oldOwnerUsername = (await oldGuild.fetchOwner()).user.username;
const newOwnerUsername = (await newGuild.fetchOwner()).user.username;
seems to not warn
Amgelo
Amgelo8mo ago
do consider that that returns a guildmember, not a user, but it still works yep
Kawaxte
KawaxteOP8mo ago
seems more idiomatic since we are directly calling from the guild cache, if any
Amgelo
Amgelo8mo ago
users.fetch also checks cache iirc
Kawaxte
KawaxteOP8mo ago
at least i don't have to do this absolute disgust in Disc.js
let guild = guild.as_ref().expect("Guild is not available");
let guild_id = &guild.id;
let guild_name = &guild.name;
let guild = guild.as_ref().expect("Guild is not available");
let guild_id = &guild.id;
let guild_name = &guild.name;
i'm so thanksful for built-in helper functions just get a guild arg directly and call from there now i'll have to test out that event to see if it's correct but for now, issue ist solved. thank you!
Want results from more Discord servers?
Add your server