function parseOption(option) {
  if (typeof option === 'string' || Array.isArray(option)) {
    return parseOption({
      name: option
    })
  }

  /**
   * @typedef {object} StepForTest
   * @property {Matcher} test
   * @property {undefined} [wildcard]
   * @typedef {object} StepForWildcard
   * @property {undefined} [test]
   * @property {true} wildcard
   * @typedef {StepForTest | StepForWildcard} Step
   */

  /** @type {Step[]} */
  const steps = []
  for (const name of Array.isArray(option.name) ? option.name : [option.name]) {
    if (name === '*') {
      steps.push({ wildcard: true })
    } else {
      steps.push({ test: buildMatcher(name) })
    }
  }
  const message = option.message

  return {
    test: buildTester(0),
    message
  }

  /**
   * @param {number} index
   * @returns {Tester}
   */
  function buildTester(index) {
    const step = steps[index]
    const next = index + 1
    const needNext = steps.length > next
    return (node) => {
      /** @type {string} */
      let keyName
      if (step.wildcard) {
        keyName = '*'
      } else {
        if (node.type !== 'Property') {
          return null
        }
        const name = utils.getStaticPropertyName(node)
        if (!name || !step.test(name)) {
          return null
        }
        keyName = name
      }

      return {
        next: needNext ? buildTester(next) : undefined,
        wildcard: step.wildcard,
        keyName
      }
    }
  }
}
@param {string | string[] | { name: string | string[], message?: string } } option
@returns {ParsedOption}