Skip to main content
Glama
example.md15.1 kB
## Example ```typescript before /** @derive(PartialEq, Hash) */ class User { id: number; name: string; @partialEq(skip) // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; } ``` ```typescript after class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` Generated output: ```typescript before class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` ```typescript after class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` Generated output: ```typescript before class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` ```typescript after class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` Generated output: ```typescript before class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` ```typescript after class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` Generated output: ```typescript before class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` ```typescript after class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` Generated output: ```typescript before class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` ```typescript after class User { id: number; name: string; // Don't compare cached values /** @hash({ skip: true }) */ cachedScore: number; equals(other: unknown): boolean { if (this === other) return true; if (!(other instanceof User)) return false; const typedOther = other as User; return this.id === typedOther.id && this.name === typedOther.name; } hashCode(): number { let hash = 17; hash = (hash * 31 + (Number.isInteger(this.id) ? this.id | 0 : this.id .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; hash = (hash * 31 + (this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) | 0; hash = (hash * 31 + (Number.isInteger(this.cachedScore) ? this.cachedScore | 0 : this.cachedScore .toString() .split('') .reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) | 0; return hash; } } ``` ## Equality Contract When implementing `PartialEq`, consider also implementing `Hash`: - **Reflexivity**: `a.equals(a)` is always true - **Symmetry**: `a.equals(b)` implies `b.equals(a)` - **Hash consistency**: Equal objects must have equal hash codes

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/macroforge-ts/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server