{"id":10519,"library":"assert-never","title":"Assert Never Utility","description":"The `assert-never` package provides a lightweight helper function designed for TypeScript's exhaustive checks on discriminated unions. Its primary purpose is to ensure that all possible cases of a union type are handled within a conditional block, leveraging the TypeScript compiler to catch unhandled cases at compile time. At runtime, if an unhandled case is encountered, `assertNever` will throw an `Error` by default, indicating a logical flaw. Alternatively, it can be configured to fail silently. The current stable version is 1.4.0. As a focused utility for a core TypeScript pattern, its release cadence is typically infrequent, with updates primarily for compatibility or minor feature enhancements rather than rapid iteration. Its key differentiator is its simplicity and direct application for a common TypeScript development pattern, making union type handling more robust.","status":"active","version":"1.4.0","language":"javascript","source_language":"en","source_url":"https://github.com/aikoven/assert-never","tags":["javascript","typescript","discriminated unions","assert","never"],"install":[{"cmd":"npm install assert-never","lang":"bash","label":"npm"},{"cmd":"yarn add assert-never","lang":"bash","label":"yarn"},{"cmd":"pnpm add assert-never","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library is primarily designed for ES modules and TypeScript. CommonJS users should use named property access.","wrong":"const assertNever = require('assert-never').assertNever;","symbol":"assertNever","correct":"import { assertNever } from 'assert-never';"}],"quickstart":{"code":"import { assertNever } from \"assert-never\";\n\ntype Shape =\n  | { type: 'circle'; radius: number }\n  | { type: 'square'; side: number }\n  | { type: 'triangle'; base: number; height: number };\n\nfunction getArea(shape: Shape): number {\n  switch (shape.type) {\n    case 'circle':\n      return Math.PI * shape.radius ** 2;\n    case 'square':\n      return shape.side ** 2;\n    // If 'triangle' was added to Shape but not handled here, TypeScript would error.\n    default:\n      // TypeScript will error here if there are unhandled types in the union.\n      // At runtime, if an unhandled shape reaches this point, it will throw an Error.\n      return assertNever(shape);\n  }\n}\n\n// Example usage\nconst myCircle: Shape = { type: 'circle', radius: 5 };\nconst mySquare: Shape = { type: 'square', side: 4 };\nconst myTriangle: Shape = { type: 'triangle', base: 3, height: 6 };\n\nconsole.log(\"Area of circle:\", getArea(myCircle));\nconsole.log(\"Area of square:\", getArea(mySquare));\nconsole.log(\"Area of triangle:\", getArea(myTriangle));\n\n// To demonstrate the runtime error (uncomment the next lines to run):\n// type NewShape = Shape | { type: 'pentagon'; side: number };\n// const unhandledShape: NewShape = { type: 'pentagon', side: 5 };\n// try {\n//   // This line would cause a TypeScript error if getArea still expects 'Shape'\n//   // and 'pentagon' is not handled. For runtime demo, we cast to bypass TS.\n//   console.log(\"Area of unhandled shape:\", getArea(unhandledShape as Shape));\n// } catch (e: any) {\n//   console.error(\"Caught expected runtime error:\", e.message);\n// }","lang":"typescript","description":"This example demonstrates how `assertNever` is used within a TypeScript switch statement to ensure exhaustive handling of a discriminated union `Shape`. If a new type is added to `Shape` but not handled in `getArea`, TypeScript will raise a compile-time error at the `assertNever` call. At runtime, if an unhandled type reaches this point, `assertNever` will throw an error."},"warnings":[{"fix":"To prevent runtime errors, ensure all union cases are handled, or explicitly opt for silent failure with `assertNever(value, true)`.","message":"The primary purpose of `assertNever` is to throw a runtime Error if an unhandled case is encountered, signaling an unexpected state. If silent failure or custom logging is desired, pass `true` as the second argument: `assertNever(value, true)`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Enable `strict: true` in your `tsconfig.json` or individually enable `strictNullChecks`, `noImplicitReturns`, and `noFallthroughCasesInSwitch`.","message":"This library relies on TypeScript's type inference and strictness for compile-time exhaustive checks. For this pattern to function correctly, ensure your `tsconfig.json` has `strict: true` (or at least `strictNullChecks`, `noImplicitReturns`, and `noFallthroughCasesInSwitch`) enabled.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add additional `if` or `case` statements to handle all remaining types in your discriminated union before the call to `assertNever`.","cause":"You have not exhaustively handled all cases of the discriminated union before calling `assertNever`. TypeScript correctly identifies that there are still possible types remaining that could be passed to `assertNever`, which expects 'never'.","error":"Argument of type '...' is not assignable to parameter of type 'never'."},{"fix":"Review the logic preceding `assertNever` to ensure all possible runtime values are handled. If the type is correct but needs to be ignored at runtime, consider `assertNever(value, true)`.","cause":"The `assertNever` function was reached at runtime, meaning an unhandled case of the discriminated union was encountered. This indicates a logic error where a type was present that TypeScript did not prevent due to either a type assertion, a dynamic value, or an incomplete exhaustive check.","error":"Unhandled value in exhaustive check: [object Object]"}],"ecosystem":"npm"}