function parseOptions(type, options, defaultOptions) {
  /** @type {IndentOptions} */
  const ret = Object.assign(
    {
      indentChar: ' ',
      indentSize: 2,
      baseIndent: 0,
      attribute: 1,
      closeBracket: {
        startTag: 0,
        endTag: 0,
        selfClosingTag: 0
      },
      switchCase: 0,
      alignAttributesVertically: true,
      ignores: []
    },
    defaultOptions
  )

  if (Number.isSafeInteger(type)) {
    ret.indentSize = Number(type)
  } else if (type === 'tab') {
    ret.indentChar = '\t'
    ret.indentSize = 1
  }

  if (options.baseIndent != null && Number.isSafeInteger(options.baseIndent)) {
    ret.baseIndent = options.baseIndent
  }
  if (options.attribute != null && Number.isSafeInteger(options.attribute)) {
    ret.attribute = options.attribute
  }
  if (Number.isSafeInteger(options.closeBracket)) {
    const num = Number(options.closeBracket)
    ret.closeBracket = {
      startTag: num,
      endTag: num,
      selfClosingTag: num
    }
  } else if (options.closeBracket) {
    ret.closeBracket = Object.assign(
      {
        startTag: 0,
        endTag: 0,
        selfClosingTag: 0
      },
      options.closeBracket
    )
  }
  if (options.switchCase != null && Number.isSafeInteger(options.switchCase)) {
    ret.switchCase = options.switchCase
  }

  if (options.alignAttributesVertically != null) {
    ret.alignAttributesVertically = options.alignAttributesVertically
  }
  if (options.ignores != null) {
    ret.ignores = options.ignores
  }

  return ret
}
Normalize options.
@param {number|"tab"|undefined} type The type of indentation.
@param {IndentUserOptions} options Other options.
@param {Partial<IndentOptions>} defaultOptions The default value of options.
@returns {IndentOptions} Normalized options.