fix(structures): correctly check if flags are present (#11404)

* fix(structures): correctly check if flags are present

* chore: isFieldSet type guard

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Qjuh
2026-01-27 17:47:56 +01:00
committed by GitHub
parent 323d8e7571
commit 7a7fecbe3c
4 changed files with 41 additions and 9 deletions

View File

@@ -3,7 +3,7 @@ import type { APIChannel, APIPartialChannel, ChannelType, ChannelFlags } from 'd
import { Structure } from '../Structure.js'; import { Structure } from '../Structure.js';
import { ChannelFlagsBitField } from '../bitfields/ChannelFlagsBitField.js'; import { ChannelFlagsBitField } from '../bitfields/ChannelFlagsBitField.js';
import { kData } from '../utils/symbols.js'; import { kData } from '../utils/symbols.js';
import { isIdSet } from '../utils/type-guards.js'; import { isFieldSet, isIdSet } from '../utils/type-guards.js';
import type { Partialize } from '../utils/types.js'; import type { Partialize } from '../utils/types.js';
import type { ChannelPermissionMixin } from './mixins/ChannelPermissionMixin.js'; import type { ChannelPermissionMixin } from './mixins/ChannelPermissionMixin.js';
import type { ChannelWebhookMixin } from './mixins/ChannelWebhookMixin.js'; import type { ChannelWebhookMixin } from './mixins/ChannelWebhookMixin.js';
@@ -82,9 +82,9 @@ export class Channel<
* to null, respecting Omit behaviors * to null, respecting Omit behaviors
*/ */
public get flags() { public get flags() {
const flags = return isFieldSet(this[kData], 'flags', 'number')
'flags' in this[kData] && typeof this[kData].flags === 'number' ? (this[kData].flags as ChannelFlags) : null; ? new ChannelFlagsBitField(this[kData].flags as ChannelFlags)
return flags ? new ChannelFlagsBitField(flags) : null; : null;
} }
/** /**

View File

@@ -2,6 +2,7 @@ import type { APIAttachment, AttachmentFlags } from 'discord-api-types/v10';
import { Structure } from '../Structure.js'; import { Structure } from '../Structure.js';
import { AttachmentFlagsBitField } from '../bitfields/AttachmentFlagsBitField.js'; import { AttachmentFlagsBitField } from '../bitfields/AttachmentFlagsBitField.js';
import { kData } from '../utils/symbols.js'; import { kData } from '../utils/symbols.js';
import { isFieldSet } from '../utils/type-guards.js';
import type { Partialize } from '../utils/types.js'; import type { Partialize } from '../utils/types.js';
export class Attachment<Omitted extends keyof APIAttachment | '' = ''> extends Structure<APIAttachment, Omitted> { export class Attachment<Omitted extends keyof APIAttachment | '' = ''> extends Structure<APIAttachment, Omitted> {
@@ -112,7 +113,8 @@ export class Attachment<Omitted extends keyof APIAttachment | '' = ''> extends S
* Attachment flags combined as a bitfield * Attachment flags combined as a bitfield
*/ */
public get flags() { public get flags() {
const flags = this[kData].flags; return isFieldSet(this[kData], 'flags', 'number')
return flags ? new AttachmentFlagsBitField(this[kData].flags as AttachmentFlags) : null; ? new AttachmentFlagsBitField(this[kData].flags as AttachmentFlags)
: null;
} }
} }

View File

@@ -4,7 +4,7 @@ import { Structure } from '../Structure.js';
import { MessageFlagsBitField } from '../bitfields/MessageFlagsBitField.js'; import { MessageFlagsBitField } from '../bitfields/MessageFlagsBitField.js';
import { dateToDiscordISOTimestamp } from '../utils/optimization.js'; import { dateToDiscordISOTimestamp } from '../utils/optimization.js';
import { kData, kEditedTimestamp } from '../utils/symbols.js'; import { kData, kEditedTimestamp } from '../utils/symbols.js';
import { isIdSet } from '../utils/type-guards.js'; import { isFieldSet, isIdSet } from '../utils/type-guards.js';
import type { Partialize } from '../utils/types.js'; import type { Partialize } from '../utils/types.js';
// TODO: missing substructures: application // TODO: missing substructures: application
@@ -110,8 +110,9 @@ export class Message<Omitted extends keyof APIMessage | '' = 'edited_timestamp'
* The flags of this message as a bit field * The flags of this message as a bit field
*/ */
public get flags() { public get flags() {
const flags = this[kData].flags; return isFieldSet(this[kData], 'flags', 'number')
return flags ? new MessageFlagsBitField(this[kData].flags as MessageFlags) : null; ? new MessageFlagsBitField(this[kData].flags as MessageFlags)
: null;
} }
/** /**

View File

@@ -1,3 +1,32 @@
export function isIdSet(id: unknown): id is bigint | string { export function isIdSet(id: unknown): id is bigint | string {
return typeof id === 'string' || typeof id === 'bigint'; return typeof id === 'string' || typeof id === 'bigint';
} }
interface TypeMap {
bigint: bigint;
boolean: boolean;
function(...args: any[]): unknown;
number: number;
object: object;
string: string;
symbol: symbol;
undefined: undefined;
}
export type TypeofType = keyof TypeMap;
function hasProperty<Value extends object, Key extends string>(
data: Value,
fieldName: Key,
): data is Record<Key, unknown> & Value {
return fieldName in data;
}
export function isFieldSet<Value extends object, Key extends string, Type extends TypeofType>(
data: Value,
fieldName: Key,
type: Type,
): data is Record<Key, TypeMap[Type]> & Value {
// eslint-disable-next-line valid-typeof
return hasProperty(data, fieldName) && typeof data[fieldName] === type;
}