Repository: date-fns/date-fns
File: src/formatDistance/index.ts (TypeScript)

Code before:
 * //=> 'less than 20 seconds'
 *
 * @example
 * // What is the distance from 1 January 2016
 * // to 1 January 2015, with a suffix?
 * const result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {
 *   addSuffix: true
 * })
 * //=> 'about 1 year ago'
 *
 * @example
 * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
 * import { eoLocale } from 'date-fns/locale/eo'
 * const result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {
 *   locale: eoLocale
 * })
 * //=> 'pli ol 1 jaro'
 */

export interface Options {
  includeSeconds?: boolean
  addSuffix?: boolean
  locale?: Locale
}

export default function formatDistance(dirtyDate: Date | number, dirtyBaseDate: Date | number, dirtyOptions?: Options) {
  requiredArgs(2, arguments)

  const options = dirtyOptions || {}
  const locale = options.locale || defaultLocale

  if (!locale.formatDistance) {
    throw new RangeError('locale must contain formatDistance property')
  }

  const comparison = compareAsc(dirtyDate, dirtyBaseDate)

  if (isNaN(comparison)) {
    throw new RangeError('Invalid time value')
  }

  const localizeOptions = cloneObject(options)
  localizeOptions.addSuffix = Boolean(options.addSuffix)
  localizeOptions.comparison = comparison

  let dateLeft
  let dateRight
  if (comparison > 0) {
    dateLeft = toDate(dirtyBaseDate)
    dateRight = toDate(dirtyDate)
  } else {

Review comment (suggestion):
Please import and use shared types from https://github.com/date-fns/date-fns/blob/master/src/types.ts

```suggestion
export default function formatDistance(dirtyDate: Date | number, dirtyBaseDate: Date | number, options : LocaleOptions & { includeSeconds?: boolean, addSuffix?: boolean } = {}) {
```

I appreciate the effort of exporting the type, but unless it's a common approach in the whole library, we don't want to do it. So please remove the exported type and put the type inline as I suggested. In the future, we might opt to export option types, but we'll need to think about the naming convention first.

Code after:
 * )
 * //=> 'less than 20 seconds'
 *
 * @example
 * // What is the distance from 1 January 2016
 * // to 1 January 2015, with a suffix?
 * const result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {
 *   addSuffix: true
 * })
 * //=> 'about 1 year ago'
 *
 * @example
 * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
 * import { eoLocale } from 'date-fns/locale/eo'
 * const result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {
 *   locale: eoLocale
 * })
 * //=> 'pli ol 1 jaro'
 */


export default function formatDistance(dirtyDate: Date | number, dirtyBaseDate: Date | number, options: LocaleOptions & { includeSeconds?: boolean, addSuffix?: boolean } = {}): string {
  requiredArgs(2, arguments)

  const locale = options.locale || defaultLocale

  if (!locale.formatDistance) {
    throw new RangeError('locale must contain formatDistance property')
  }

  const comparison = compareAsc(dirtyDate, dirtyBaseDate)

  if (isNaN(comparison)) {
    throw new RangeError('Invalid time value')
  }

  const localizeOptions = cloneObject(options)
  localizeOptions.addSuffix = Boolean(options.addSuffix)
  localizeOptions.comparison = comparison

  let dateLeft
  let dateRight
  if (comparison > 0) {
    dateLeft = toDate(dirtyBaseDate)
    dateRight = toDate(dirtyDate)
  } else {
    dateLeft = toDate(dirtyDate)
    dateRight = toDate(dirtyBaseDate)
  }

  const seconds = differenceInSeconds(dateRight, dateLeft)