{"id":30758791,"url":"https://github.com/neg4n/bitf","last_synced_at":"2025-09-04T11:13:00.593Z","repository":{"id":312673651,"uuid":"1038791351","full_name":"neg4n/bitf","owner":"neg4n","description":"A tiny and robust library to manage bitflags / bitsets / optionsets in TypeScript \u0026 JavaScript","archived":false,"fork":false,"pushed_at":"2025-09-01T09:41:27.000Z","size":101,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-01T10:48:16.645Z","etag":null,"topics":["bitflags","bitmasks","bitset","bitset-library","bun","javascript","nodejs","optionset","typescript"],"latest_commit_sha":null,"homepage":"https://neg4n.dev/blog/everything-about-bitflags","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neg4n.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-15T20:31:12.000Z","updated_at":"2025-09-01T09:45:18.000Z","dependencies_parsed_at":"2025-09-01T10:58:26.283Z","dependency_job_id":null,"html_url":"https://github.com/neg4n/bitf","commit_stats":null,"previous_names":["neg4n/bitf"],"tags_count":1,"template":false,"template_full_name":"neg4n/typescript-library-template","purl":"pkg:github/neg4n/bitf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fbitf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fbitf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fbitf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fbitf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neg4n","download_url":"https://codeload.github.com/neg4n/bitf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fbitf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273596972,"owners_count":25134262,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitflags","bitmasks","bitset","bitset-library","bun","javascript","nodejs","optionset","typescript"],"created_at":"2025-09-04T11:12:57.512Z","updated_at":"2025-09-04T11:13:00.569Z","avatar_url":"https://github.com/neg4n.png","language":"TypeScript","readme":"# bitf\n\n`bitf` is a tiny and fast bit flags _(other terms: bit fields, optionsets)_ management library for TypeScript/JavaScript\n\n## What are bitflags?\n\nBitflags are a way to represent a set of boolean options using a single integer. Each bit in the number corresponds to a different option, allowing for efficient storage and manipulation of multiple flags at once. Concept of creating this library originates from the article [\"Everything About Bitflags\"](https://neg4n.dev/blog/everything-about-bitflags).\n\n### Features\n\n- Type safety via [Tagged](https://github.com/sindresorhus/type-fest/blob/main/source/tagged.d.ts) types.\n- Lightweight and fast, almost native bitwise performance with minimal abstraction layer.\n- No runtime dependencies.\n- Robust and ready-to-use on production.\n- Comprehensive tests suite with 100% test coverage.\n- `.describe()` iterator for better debugging and visualization of the bit flags.\n- Range guards while defining bit flags.\n\n## Installation\n\n```bash\nnpm i bitf\n# or\nyarn add bitf\n# or\npnpm add bitf\n# or\nbun add bitf\n```\n\n## Usage Example\n\n\nThis example shows a pizza ordering system where customers can customize their toppings. The restaurant starts with a default Pepperoni pizza and enforces three business rules:\n\n1. cheese must always be included (it's the base of toppings every pizza being sold)\n2. only one meat type is allowed per pizza (to ensure good taste combinations)\n3. customers get an automatic discount when they order a Hawaiian pizza (cheese + ham + pineapple)\n\nThe code uses bitflags to efficiently track which toppings are selected and validate these rules, demonstrating how bitflags can handle complex combinations while enforcing business logic and detecting special cases for promotions without hundreds of lines of code of copying, modyfing and iterating over `Object`s and `Array`s of `Object`s and mapping boolean states and wasting the network bandwidth.\n\n```ts\nimport { type Bitflag, bitflag, defineBitflags } from \"bitf\";\n\n// This should probably live in a file shared between frontend/backend contexts\nconst Toppings = defineBitflags({\n  CHEESE: 1 \u003c\u003c 0,\n  PEPPERONI: 1 \u003c\u003c 1,\n  MUSHROOMS: 1 \u003c\u003c 2,\n  OREGANO: 1 \u003c\u003c 3,\n  PINEAPPLE: 1 \u003c\u003c 4,\n  BACON: 1 \u003c\u003c 5,\n  HAM: 1 \u003c\u003c 6,\n});\n\n// Can be mapped on frontend using InferBitflagsDefinitions\u003ctypeof Toppings\u003e and .describe() function\ntype PizzaOrderPreferences = Readonly\u003c{\n  desiredSize: \"small\" | \"medium\" | \"large\";\n  toppingsToAdd: Bitflag;\n  toppingsToRemove: Bitflag;\n}\u003e;\n\nexport async function configurePizzaOrder({\n  desiredSize,\n  toppingsToAdd,\n  toppingsToRemove,\n}: PizzaOrderPreferences) {\n  if (bitflag(toppingsToRemove).has(Toppings.CHEESE))\n    throw new Error(\"Cheese is always included in our pizzas!\");\n\n  const defaultPizza = bitflag().add(Toppings.CHEESE, Toppings.PEPPERONI);\n  const pizzaAfterRemoval = processToppingsRemoval(\n    defaultPizza,\n    toppingsToRemove\n  );\n\n  validateMeatAddition(pizzaAfterRemoval, toppingsToAdd);\n\n  // ... some additional logic like checking the toppings availability in the restaurant inventory\n  // ... some additional logging using the .describe() function for comprehensive info\n\n  const finalPizza = bitflag(pizzaAfterRemoval).add(toppingsToAdd);\n\n  return {\n    size: desiredSize,\n    pizza: finalPizza,\n    metadata: {\n      hawaiianPizzaDiscount: bitflag(finalPizza).hasExact(\n        Toppings.CHEESE,\n        Toppings.HAM,\n        Toppings.PINEAPPLE\n      ),\n    },\n  };\n}\n\nfunction processToppingsRemoval(\n  currentPizza: Bitflag,\n  toppingsToRemove: Bitflag\n) {\n  if (toppingsToRemove) return bitflag(currentPizza).remove(toppingsToRemove);\n  return currentPizza;\n}\n\nfunction validateMeatAddition(currentPizza: Bitflag, toppingsToAdd: Bitflag) {\n  const currentHasMeat = bitflag(currentPizza).hasAny(\n    Toppings.PEPPERONI,\n    Toppings.BACON,\n    Toppings.HAM\n  );\n\n  const requestingMeat = bitflag(toppingsToAdd).hasAny(\n    Toppings.PEPPERONI,\n    Toppings.BACON,\n    Toppings.HAM\n  );\n\n  if (currentHasMeat \u0026\u0026 requestingMeat)\n    throw new Error(\"Only one type of meat is allowed per pizza!\");\n}\n```\n\n## Top-level API\n\n`bitf` library exposes the following:\n\n**Core runtime functionality:**\n\n- [`bitflag`](#bitflagbitflag--number) - the main function to perform bitwise operations on the flags.\n  - Bitwise operations abstraction\n    - [`has`](#hasbitflag) - checks if the specified flags are set\n    - [`hasAny`](#hasanybitflag) - checks if any of the specified flags are set\n    - [`hasExact`](#hasexactbitflag) - checks if the specified flags are set exactly\n    - [`add`](#addbitflag) - adds the specified flags\n    - [`remove`](#removebitflag) - removes the specified flags\n    - [`toggle`](#togglebitflag) - toggles the specified flags\n    - [`clear`](#clear) - clears all flags\n  - Debugging and visualization\n    - [`describe`](#describeflagdefinitions-bitflagsdefinitionst) - returns an iterator for describing the flags\n  - Interoperability between the library and other code\n    - [`value`](#value) - returns the current value of the flags\n    - [`valueOf`](#valueof) - returns the current value of the flags\n    - [`toString`](#tostring) - returns the string representation of the flags\n- [`defineBitflags`](#definebitflagst-extends-recordstring-numberobj-t) - utility to define type-safe set of bit flags\n\n\u003e [!NOTE]\n\u003e All of the operations support passing multiple flags at once through variadic arguments.\n\n**Utility functions**\n\n- [`makeBitflag`](#makebitflagvalue-number) - utility to create a `Bitflag` Tagged Type from a number if it is possible.\n- [`isBitflag`](#isbitflagvalue-unknown) - utility to check if number is within allowed range and to create a `Bitflag` Tagged type out of it\n- [`unwrapBitflag`](#unwrapbitflagflag-bitflag) - utility to unwrap the Tagged type of `Bitflag` to be just `number`\n\n**Type utilities**\n\n- `Bitflag` - The tagged type for individual bitflag numbers\n- `BitflagsDefinitions\u003cT\u003e` - The type for frozen bitflag definition objects returned by `defineBitflags`\n- `InferBitflagsDefinitions\u003cT\u003e` - Type utility to extract the shape from bitflag definitions (similar to Zod's `z.infer`)\n\n## API Reference\n\n### `bitflag(Bitflag | number)`\n\nBitflag is a factory function that returns object with a specific set of operations for managing the flags. It accepts any number or `Bitflag` Tagged Type as an argument and then allows you to perform various operations on it. It also supports methods like `toString()`, `value` getter and `valueOf()` for compatibility with other JavaScript APIs.\n\n**Important:** The `bitflag` function's returned object's methods are **non-chainable** - each call to the bitwise operations returns just a number wrapped with the `Bitflag` Tagged Type. It does not return a new instance of the `bitflag` object.\n\n#### Correct Usage\n\n```ts\nconst combinedFlags = bitflag(flags.NONE).add(\n  flags.MY_OTHER_FLAG,\n  flags.ANOTHER_FLAG\n);\n\nif (bitflag(combinedFlags).has(flags.ANOTHER_FLAG)) {\n  console.log(\"has ANOTHER_FLAG\");\n}\n```\n\n#### Incorrect Usage\n\n```ts\n// ❌ This will not work as expected\nif (\n  bitflag(flags.NONE)\n    .add(flags.MY_OTHER_FLAG, flags.ANOTHER_FLAG)\n    .has(flags.ANOTHER_FLAG)\n) {\n  console.log(\"has ANOTHER_FLAG\");\n}\n```\n\n### Bitwise Operations\n\n### `.has(...Bitflag[])`\n\nChecks if all the specified flags are set in the current set. Returns `true` if all flags are present, `false` otherwise.\n\n**Tip:** Passing no arguments to `.has()` always returns `false`.\n\n#### Examples\n\n```ts\nbitflag(flags.READ | flags.WRITE).has(flags.READ); // single defined\nbitflag(flags.READ | flags.WRITE | flags.EXECUTE).has(\n  flags.READ,\n  flags.WRITE\n); // multiple defined\nbitflag(flags.READ | flags.WRITE).has(flags.READ, makeBitflag(1 \u003c\u003c 1)); // mixed\n```\n\n### `.hasAny(...Bitflag[])`\n\nChecks if any of the specified flags are set in the current set. Returns `true` if at least one flag is present, `false` if none are present.\n\n**Tip:** Passing no arguments to `.hasAny()` always returns `false`.\n\n#### Examples\n\n```ts\nbitflag(flags.READ | flags.WRITE).hasAny(flags.EXECUTE); // single defined\nbitflag(flags.READ).hasAny(flags.EXECUTE, flags.DELETE); // multiple defined\nbitflag(flags.READ).hasAny(flags.EXECUTE, makeBitflag(1 \u003c\u003c 0)); // mixed\n```\n\n### `.hasExact(...Bitflag[])`\n\nChecks if the current set matches exactly the specified flags - no more, no less. Returns `true` if the flags match exactly, `false` otherwise.\n\n**Tip:** Calling `.hasExact()` with no arguments checks if the current value is exactly zero.\n\n#### Examples\n\n```ts\nbitflag(flags.READ | flags.WRITE).hasExact(flags.READ, flags.WRITE); // single defined exact match\nbitflag(flags.NONE).hasExact(); // multiple defined (empty means zero flags)\nbitflag(flags.READ).hasExact(makeBitflag(1 \u003c\u003c 0)); // mixed\n```\n\n### `.add(...Bitflag[])`\n\nAdds the specified flags to the current set. Returns a new number wrapped in `Bitflag\u003cT\u003e` as the updated flags.\n\n**Tip:** Adding the same flag multiple times is idempotent - it won't change the result.\n\n#### Examples\n\n```ts\nbitflag(flags.MY_FLAG).add(flags.MY_OTHER_FLAG); // single defined\nbitflag(flags.MY_FLAG).add(flags.MY_OTHER_FLAG, flags.ANOTHER_FLAG); // multiple defined\nbitflag(flags.MY_FLAG).add(flags.MY_OTHER_FLAG, makeBitflag(1 \u003c\u003c 2)); // mixed\n```\n\n### `.remove(...Bitflag[])`\n\nRemoves the specified flags from the current set. Returns a new number wrapped in `Bitflag\u003cT\u003e` as the updated flags.\n\n**Tip:** Removing non-existent flags has no effect and won't change the result.\n\n#### Examples\n\n```ts\nbitflag(flags.READ | flags.WRITE).remove(flags.WRITE); // single defined\nbitflag(flags.ALL).remove(flags.WRITE, flags.DELETE); // multiple defined\nbitflag(flags.READ | flags.WRITE).remove(flags.WRITE, makeBitflag(1 \u003c\u003c 3)); // mixed\n```\n\n### `.toggle(...Bitflag[])`\n\nToggles the specified flags in the current set - adds them if not present, removes them if present. Returns a new number wrapped in `Bitflag\u003cT\u003e` as the updated flags.\n\n#### Examples\n\n```ts\nbitflag(flags.READ).toggle(flags.WRITE); // single defined\nbitflag(flags.READ | flags.EXECUTE).toggle(flags.WRITE, flags.EXECUTE); // multiple defined\nbitflag(flags.read).toggle(flags.WRITE, makeBitflag(1 \u003c\u003c 4)); // mixed\n```\n\n### `.clear()`\n\nClears all flags, setting the value to zero. Returns a new number wrapped in `Bitflag\u003cT\u003e` with value 0.\n\n#### Examples\n\n```ts\nbitflag(flags.ALL).clear(); // returns 0 as Bitflag\n```\n\n### Debugging and Visualization\n\n### `.describe(flagDefinitions?: BitflagsDefinitions\u003cT\u003e)`\n\nReturns an iterator that yields `FlagDescription` objects for each set bit, providing detailed information about the flags including name, value, and bit position visualization.\n\n#### FlagDescription Structure\n\n```ts\ntype FlagDescription = {\n  name: string; // Flag name or \"BIT_X\"/\"UNKNOWN_BIT_X\"\n  value: number; // Numeric value of this specific flag\n  decimal: string; // Decimal representation (e.g., \"42\")\n  hexadecimal: string; // Hexadecimal with 0x prefix (e.g., \"0x2A\")\n  binary: string; // Binary with 0b prefix (e.g., \"0b101010\")\n  unknown: boolean; // true if flag not found in the definitions provided via parameter\n  bitPosition: {\n    exact: number; // Highest bit position (-1 for zero)\n    remaining: number; // Remaining available bit positions\n    visual: string; // Visual bit representation with [1] markers\n  };\n};\n```\n\n#### Examples\n\n**Basic Usage with Flag Definitions**\n\n```ts\n[...bitflag(flags.READ | flags.WRITE).describe(flags)];\n```\n\nReturns:\n```js\n[\n  {\n    name: \"READ\",\n    value: 1,\n    decimal: \"1\",\n    hexadecimal: \"0x1\",\n    binary: \"0b1\",\n    unknown: false,\n    bitPosition: {\n      exact: 0,\n      remaining: 31,\n      visual: \"(0)000000000000000000000000000000[1]\",\n    },\n  },\n  {\n    name: \"WRITE\",\n    value: 2,\n    decimal: \"2\",\n    hexadecimal: \"0x2\",\n    binary: \"0b10\",\n    unknown: false,\n    bitPosition: {\n      exact: 1,\n      remaining: 30,\n      visual: \"(0)00000000000000000000000000000[1]0\",\n    },\n  },\n]\n```\n\n**Generic Bit Names (No Definitions)**\n\n```ts\n// Without definitions - shows generic BIT_X names\n[...bitflag(5).describe()]; // value 5 = bits 0 and 2\n```\n\nReturns:\n```js\n[\n  {\n    name: \"BIT_0\",\n    value: 1,\n    binary: \"0b1\",\n    unknown: false,\n    bitPosition: {\n      exact: 0,\n      remaining: 31,\n      visual: \"(0)000000000000000000000000000000[1]\",\n    },\n  },\n  {\n    name: \"BIT_2\",\n    value: 4,\n    binary: \"0b100\",\n    unknown: false,\n    bitPosition: {\n      exact: 2,\n      remaining: 29,\n      visual: \"(0)0000000000000000000000000000[1]00\",\n    },\n  },\n]\n```\n\n**Mixed Known and Unknown Flags**\n\n```ts\n// Mixed known and unknown flags\n[...bitflag(flags.READ | makeBitflag(1 \u003c\u003c 10)).describe(flags)];\n```\n\nReturns:\n```js\n[\n  {\n    name: \"READ\",\n    value: 1,\n    decimal: \"1\",\n    hexadecimal: \"0x1\",\n    binary: \"0b1\",\n    unknown: false,\n    bitPosition: {\n      exact: 0,\n      remaining: 31,\n      visual: \"(0)000000000000000000000000000000[1]\",\n    },\n  },\n  {\n    name: \"UNKNOWN_BIT_10\",\n    value: 1024,\n    decimal: \"1024\",\n    hexadecimal: \"0x400\",\n    binary: \"0b10000000000\",\n    unknown: true,\n    bitPosition: {\n      exact: 10,\n      remaining: 21,\n      visual: \"(0)00000000000000000000[1]0000000000\",\n    },\n  },\n]\n```\n\n**Zero Value Special Case**\n\n```ts\n// Zero value special case\n[...bitflag(0).describe()];\n```\n\nReturns:\n```js\n[\n  {\n    name: \"NONE\",\n    value: 0,\n    decimal: \"0\",\n    hexadecimal: \"0x0\",\n    binary: \"0b0\",\n    unknown: false,\n    bitPosition: {\n      exact: -1,\n      remaining: 31,\n      visual: \"(0)0000000000000000000000000000000\",\n    },\n  },\n]\n```\n\n**High Bit Positions (15 \u0026 30)**\n\n```ts\n// High bit positions (bit 15 and 30)\n[...bitflag(makeBitflag((1 \u003c\u003c 15) | (1 \u003c\u003c 30))).describe()];\n```\n\nReturns:\n```js\n[\n  {\n    name: \"BIT_15\",\n    value: 32768,\n    binary: \"0b1000000000000000\",\n    bitPosition: {\n      exact: 15,\n      remaining: 16,\n      visual: \"(0)000000000000000[1]000000000000000\",\n    },\n  },\n  {\n    name: \"BIT_30\",\n    value: 1073741824,\n    binary: \"0b1000000000000000000000000000000\",\n    bitPosition: {\n      exact: 30,\n      remaining: 1,\n      visual: \"(0)[1]000000000000000000000000000000\",\n    },\n  },\n]\n```\n\n#### Important Notes\n\n**Bit Position Visualization:** The `visual` field shows a 32-character representation where `[1]` indicates set bits and `0` shows unset bits. The format is `(0)[bit31][bit30]...[bit1][bit0]` with the sign bit always shown as `(0)`.\n\n**Flag Resolution Order:** When using flag definitions, the iterator yields known flags first (in the order they match), then unknown bits as `UNKNOWN_BIT_X` in ascending bit order.\n\n**Complex Flags:** Combined flags (like `READ_WRITE: (1\u003c\u003c0)|(1\u003c\u003c1)`) are detected when their exact bit pattern matches the current value, alongside their individual component flags.\n\n### Interoperability between the library and other code\n\n### `.value`\n\nA getter that returns the current numeric value of the flags as a regular number.\n\n#### Examples\n\n```ts\nbitflag(flags.READ | flags.WRITE).value; // returns 3\nbitflag().value; // returns 0\nbitflag(flags.ALL).value; // returns the combined numeric value\n```\n\n### `.valueOf()`\n\nReturns the current numeric value of the flags, enabling implicit conversion to number in JavaScript operations.\n\n#### Examples\n\n```ts\nbitflag(flags.READ).valueOf(); // explicit call\n+bitflag(flags.WRITE); // implicit conversion\nNumber(bitflag(flags.EXECUTE)); // explicit conversion\n```\n\n### `.toString()`\n\nReturns the string representation of the current numeric value of the flags.\n\n#### Examples\n\n```ts\nbitflag(flags.READ).toString(); // returns \"1\"\nString(bitflag(flags.READ | flags.WRITE)); // returns \"3\"\n`Current flags: ${bitflag(flags.ALL)}`; // template literal usage\n```\n\n### Utility Functions\n\n### `defineBitflags\u003cT extends Record\u003cstring, number\u003e\u003e(obj: T)`\n\nUtility function to define a type-safe set of bit flags. It validates that all values are non-negative integers within the 31-bit range and returns a frozen object with `Bitflag` Tagged Types.\n\n**Tip:** The returned object is frozen to prevent accidental modifications. All values must be within the range 0 to 0x7FFFFFFF (31-bit signed integer range).\n\n#### Examples\n\n```ts\nconst flags = defineBitflags({\n  READ: 1 \u003c\u003c 0,\n  WRITE: 1 \u003c\u003c 1,\n  EXECUTE: 1 \u003c\u003c 2,\n}); // basic usage\n\nconst complexFlags = defineBitflags({\n  NONE: 0,\n  READ: 1 \u003c\u003c 0,\n  WRITE: 1 \u003c\u003c 1,\n  READ_WRITE: (1 \u003c\u003c 0) | (1 \u003c\u003c 1),\n}); // with combined flags\n\nconst permissions = defineBitflags({\n  VIEWER: 1,\n  EDITOR: 3,\n  ADMIN: 15,\n}); // with arbitrary values\n```\n\n### `makeBitflag(value: number)`\n\nUtility function to create a `Bitflag` Tagged Type from a number if it's within the valid range. Throws an error if the conversion would result in a data loss.\n\n**Tip:** This function validates the input and throws a descriptive error for invalid values (negative numbers or values exceeding 31 bits). It is also the only function that throws.\n\n#### Examples\n\n```ts\nmakeBitflag(5); // creates Bitflag from valid number\nmakeBitflag(0); // creates Bitflag for zero\nmakeBitflag(0x7fffffff); // creates Bitflag for maximum value\n```\n\n### `isBitflag(value: unknown)`\n\nType guard utility to check if a value can be used as a `Bitflag`. Returns `true` if the value is a non-negative integer within the 31-bit range.\n\n**Tip:** This function is useful for runtime validation before using values with the bitflag operations.\n\n#### Examples\n\n```ts\nisBitflag(5); // returns true\nisBitflag(-1); // returns false\nisBitflag(1.5); // returns false\n```\n\n### `unwrapBitflag(flag: Bitflag)`\n\nUtility function to extract the numeric value from a `Bitflag` Tagged Type, converting it back to a regular number.\n\n#### Examples\n\n```ts\nconst flags = defineBitflags({ TEST: 5 });\nunwrapBitflag(flags.TEST); // returns 5 as number\nunwrapBitflag(bitflag(flags.TEST).add(makeBitflag(2))); // returns 7 as number\nunwrapBitflag(bitflag().clear()); // returns 0 as number\n```\n\n### Type Utilities\n\n### `Bitflag`\n\nThe tagged type for individual bitflag numbers. This ensures type safety by distinguishing bitflag numbers from regular numbers.\n\nIt is mostly used internally inside the library source. Export exists for complex cases where you would need this type.\n\n### `BitflagsDefinitions\u003cT\u003e`\n\nThe type for frozen bitflag definition objects returned by `defineBitflags`. This represents the complete set of flag definitions.\n\nIt is mostly used internally inside the library source. Export exists for complex cases where you would need this type.\n\n### `InferBitflagsDefinitions\u003cT\u003e`\n\nType utility to extract the shape from bitflag definitions. Converts `BitflagsDefinitions\u003cT\u003e` to `Record\u003ckeyof T, Bitflag\u003e`.\n\n#### Examples\n\n```ts\nimport { type InferBitflagsDefinitions } from \"bitf\";\n\n// Define flags\nconst UserPermissions = defineBitflags({\n  READ: 1 \u003c\u003c 0,\n  WRITE: 1 \u003c\u003c 1,\n  DELETE: 1 \u003c\u003c 2,\n});\n\n// Extract type shape\ntype UserPermissionsType = InferBitflagsDefinitions\u003ctypeof UserPermissions\u003e;\n// Result: { READ: Bitflag; WRITE: Bitflag; DELETE: Bitflag }\n```\n\n## Benchmarks\n\nSee more [\"Everything About Bitflags - Benchmarks\"](https://neg4n.dev/blog/everything-about-bitflags#benchmarks).\n\n## License\n\nThe MIT License","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneg4n%2Fbitf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneg4n%2Fbitf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneg4n%2Fbitf/lists"}