Repository: discordjs/discord.js
File: src/structures/BaseGuildVoiceChannel.js (JavaScript)

Code before:
    const coll = new Collection();
    for (const state of this.guild.voiceStates.cache.values()) {
      if (state.channelId === this.id && state.member) {
        coll.set(state.id, state.member);
      }
    }
    return coll;
  }

  /**
   * Checks if the voice-based channel is full
   * @type {boolean}
   * @readonly
   */
  get full() {
    return this.userLimit > 0 && this.members.size >= this.userLimit;
  }

  /**
   * Whether the channel is joinable by the client user
   * @type {boolean}
   * @readonly
   */
  get joinable() {
    if (!this.viewable) return false;
    const permissions = this.permissionsFor(this.client.user);
    // This flag allows joining even if timed out
    if (permissions.has(Permissions.FLAGS.ADMINISTRATOR, false)) return true;
    if (!permissions.has(Permissions.FLAGS.CONNECT, false)) return false;
    return this.guild.me.communicationDisabledUntilTimestamp < Date.now();
  }

  /**
   * Sets the RTC region of the channel.
   * @param {?string} region The new region of the channel. Set to `null` to remove a specific region for the channel
   * @returns {Promise<BaseGuildVoiceChannel>}
   * @example
   * // Set the RTC region to europe
   * channel.setRTCRegion('europe');
   * @example
   * // Remove a fixed region for this channel - let Discord decide automatically
   * channel.setRTCRegion(null);
   */
  setRTCRegion(region) {
    return this.edit({ rtcRegion: region });
  }

  /**
   * Creates an invite to this guild channel.
   * @param {CreateInviteOptions} [options={}] The options for creating the invite
   * @returns {Promise<Invite>}

Review comment (bug):
This needs a check for nullability, `permissionsFor(User)`'s return is nullable.

As for why the old code didn't account for that... it's a bug and would have thrown an error if `guild.me` was not cached.

Code after:
    const coll = new Collection();
    for (const state of this.guild.voiceStates.cache.values()) {
      if (state.channelId === this.id && state.member) {
        coll.set(state.id, state.member);
      }
    }
    return coll;
  }

  /**
   * Checks if the voice-based channel is full
   * @type {boolean}
   * @readonly
   */
  get full() {
    return this.userLimit > 0 && this.members.size >= this.userLimit;
  }

  /**
   * Whether the channel is joinable by the client user
   * @type {boolean}
   * @readonly
   */
  get joinable() {
    if (!this.viewable) return false;
    const permissions = this.permissionsFor(this.client.user);
    if (!permissions) return false;

    // This flag allows joining even if timed out
    if (permissions.has(Permissions.FLAGS.ADMINISTRATOR, false)) return true;

    return (
      this.guild.me.communicationDisabledUntilTimestamp < Date.now() &&
      permissions.has(Permissions.FLAGS.CONNECT, false)
    );
  }

  /**
   * Sets the RTC region of the channel.
   * @param {?string} region The new region of the channel. Set to `null` to remove a specific region for the channel
   * @returns {Promise<BaseGuildVoiceChannel>}
   * @example
   * // Set the RTC region to europe
   * channel.setRTCRegion('europe');
   * @example
   * // Remove a fixed region for this channel - let Discord decide automatically
   * channel.setRTCRegion(null);
   */
  setRTCRegion(region) {
    return this.edit({ rtcRegion: region });
  }