Hone logo
Hone
Problems

SemVer Type System in TypeScript

This challenge asks you to create a robust type system in TypeScript that accurately represents Semantic Versioning (SemVer) strings. A SemVer type system allows for type-safe comparisons and manipulations of version numbers, preventing common errors and improving code reliability. This is particularly useful in libraries and applications where version compatibility is critical.

Problem Description

You need to define a TypeScript type and associated functions to represent and work with SemVer strings (e.g., "1.2.3", "2.0.0-beta.1+build.123"). The type should accurately reflect the structure of a SemVer string, including major, minor, patch, pre-release, and build metadata.

What needs to be achieved:

  1. SemVer Type: Define a TypeScript type SemVer that represents a SemVer string. This type should capture the major, minor, patch, pre-release, and build metadata components. Consider using a discriminated union to represent the different possible SemVer formats (e.g., normal, pre-release, build).
  2. parseSemVer Function: Create a function parseSemVer(version: string): SemVer | null that takes a SemVer string as input and returns a SemVer object if the string is a valid SemVer string. If the input is not a valid SemVer string, the function should return null.
  3. compareSemVer Function: Create a function compareSemVer(version1: SemVer, version2: SemVer): number that takes two SemVer objects as input and returns a number indicating their relative order. The return value should follow these conventions:
    • -1: version1 is less than version2
    • 0: version1 is equal to version2
    • 1: version1 is greater than version2
  4. isValidSemVer Function: Create a function isValidSemVer(version: string): boolean that takes a SemVer string as input and returns true if the string is a valid SemVer string, and false otherwise.

Key Requirements:

  • The SemVer type must accurately represent the structure of a SemVer string.
  • The parseSemVer function must correctly parse valid SemVer strings and return a SemVer object.
  • The compareSemVer function must correctly compare two SemVer objects and return the appropriate comparison result.
  • The isValidSemVer function must correctly validate SemVer strings.
  • Handle pre-release and build metadata correctly during parsing and comparison.
  • Handle invalid SemVer strings gracefully (e.g., incorrect format, non-numeric components).

Expected Behavior:

  • parseSemVer("1.2.3") should return a SemVer object representing version "1.2.3".
  • parseSemVer("2.0.0-beta.1+build.123") should return a SemVer object representing version "2.0.0-beta.1+build.123".
  • parseSemVer("invalid-version") should return null.
  • compareSemVer({ major: 1, minor: 2, patch: 3 }, { major: 1, minor: 2, patch: 4 }) should return -1.
  • compareSemVer({ major: 1, minor: 2, patch: 3 }, { major: 1, minor: 2, patch: 3 }) should return 0.
  • compareSemVer({ major: 1, minor: 2, patch: 3 }, { major: 1, minor: 2, patch: 2 }) should return 1.
  • isValidSemVer("1.2.3") should return true.
  • isValidSemVer("invalid-version") should return false.

Edge Cases to Consider:

  • Empty strings.
  • Strings with leading or trailing whitespace.
  • Strings with non-numeric characters in the major, minor, or patch components.
  • Invalid pre-release identifiers (e.g., non-alphanumeric characters).
  • Invalid build metadata (e.g., non-alphanumeric characters).
  • Versions with only major, minor, or patch components (e.g., "1.2", "1").
  • Versions with multiple pre-release identifiers (e.g., "1.0.0-alpha.beta.1").

Examples

Example 1:

Input: parseSemVer("1.2.3")
Output: { major: 1, minor: 2, patch: 3 }
Explanation: The input is a valid SemVer string, so the function returns a SemVer object representing the version.

Example 2:

Input: compareSemVer({ major: 1, minor: 2, patch: 3 }, { major: 1, minor: 2, patch: 4 })
Output: -1
Explanation: Version 1.2.3 is less than version 1.2.4, so the function returns -1.

Example 3:

Input: isValidSemVer("invalid-version")
Output: false
Explanation: The input is not a valid SemVer string, so the function returns false.

Constraints

  • The major, minor, and patch components must be non-negative integers.
  • Pre-release identifiers and build metadata must be strings.
  • The parseSemVer function should handle invalid input gracefully and return null.
  • The compareSemVer function should handle cases where one or both versions are null (treat null as less than any valid version).
  • Performance is not a primary concern for this challenge, but avoid excessively complex or inefficient algorithms.

Notes

  • Consider using regular expressions to validate the SemVer string format.
  • Think carefully about how to represent the different components of a SemVer string in your SemVer type. A discriminated union is a good approach.
  • Pay close attention to the SemVer specification when implementing the compareSemVer function. Pre-release identifiers and build metadata have specific precedence rules.
  • Test your code thoroughly with a variety of valid and invalid SemVer strings.
  • Focus on creating a type-safe and accurate representation of SemVer strings in TypeScript.
Loading editor...
typescript