function getFlags(manualArgv, options = {}) {
  let parser = getYargsParser(manualArgv);

  if (options.noExitOnFailure) {
    // Silence console.error() logging and don't process.exit().
    // `parser.fail(false)` can be used in yargs once v17 is released.
    parser = parser.fail((msg, err) => {
      if (err) throw err;
      else if (msg) throw new Error(msg);
    });
  }

  // Augmenting yargs type with auto-camelCasing breaks in tsc@4.1.2 and @types/yargs@15.0.11,
  // so for now cast to add yarg's camelCase properties to type.
  const argv = /** @type {Awaited<typeof parser.argv>} */ (parser.argv);
  const cliFlags = /** @type {typeof argv & LH.Util.CamelCasify<typeof argv>} */ (argv);

  // yargs will return `undefined` for options that have a `coerce` function but
  // are not actually present in the user input. Instead of passing properties
  // explicitly set to undefined, delete them from the flags object.
  for (const [k, v] of Object.entries(cliFlags)) {
    if (v === undefined) delete cliFlags[k];
  }

  return cliFlags;
}
@param {string=} manualArgv
@param {{noExitOnFailure?: boolean}=} options
@return {LH.CliFlags}