function slice(v, releaseType) {
  if (!semver.valid(v, /* loose */ true)) {
    return null
  }

  const major = semver.major(v, /* loose */ true)
  const minor = semver.minor(v, /* loose */ true)
  const patch = semver.patch(v, /* loose */ true)
  const prerelease = semver.prerelease(v, /* loose */ true)

  const dottedParts = {
    major: [major],
    minor: [major, minor],
    patch: [major, minor, patch],
  }[releaseType]

  if (dottedParts === undefined) {
    throw Error(`Unknown releaseType: ${releaseType}`)
  }

  const dotted = dottedParts.join('.')
  if (prerelease) {
    return `${dotted}-${prerelease.join('.')}`
  } else {
    return dotted
  }
}
Slices the specified number of dotted parts from the given semver version.

@param {string} v - The semver version to slice
@param {string} releaseType - The release type to slice up to. Can be one of "major", "minor", or "patch"
@returns {string|null} The sliced version as a string, or null if the version is not valid
@example
slice('2.4.7', 'minor') // returns '2.4' because it slices the version string up to the minor component.
slice('2.4.7-alpha', 'patch') // returns '2.4.7-alpha' because it slices the version string up to the patch component and preserves the prerelease component.
slice('2.4', 'patch') // returns null because the version string is not valid according to semver rules.