Skip to content

[TS] collection.ensureIndex: replace overload signature with union #778

@akomm

Description

@akomm

There are currently two problems with the signature of ensureIndex

  1. A set of types, like EnsurePersistentIndexOptions and EnsureGeoIndexOptions exist, but no union type that combines the options. For example: type EnsureIndexOptions = EnsurePersistentIndexOptions | EnsureGeoIndexOptions | ...
  2. Using overloading on ensureIndex is unnecessary because the options are fit to be a tagged union.

Because you use overloading (2.) instead of using a union (which would also solve the problem 1.), this is not possible:

// need to combine it when I want to wrap ensureIndex into some logic
type EnsureIndexOptions =
  | EnsurePersistentIndexOptions
  | EnsureGeoIndexOptions
  | EnsureTtlIndexOptions
  | EnsureZkdIndexOptions
  | EnsureInvertedIndexOptions

function takesEnsureIndexOptions(opts: EnsureIndexOptions) {
  // collection API
  collection.ensureIndex(opts) // this will fail, because overload signatures are not compatible with unions
}

You need to always consider your API is not used inline and the type is inferred, but also wrapped by some consumer logic. The current design is very limited in this way.

Example of the consequences and what is needed because of overloading:

await Promise.all(
  indecies.map(indexOpts => {
    switch (indexOpts.type) {
      case "persistent":
        return col.ensureIndex(indexOpts)
      case "geo":
        return col.ensureIndex(indexOpts)
      case "inverted":
        return col.ensureIndex(indexOpts)
      case "ttl":
        return col.ensureIndex(indexOpts)
      case "zkd":
        return col.ensureIndex(indexOpts)
    }
  })

Its also possible to map the Options to the Return type using conditionals. I assume that was the initial consideration when the overload API was picked? Maybe it was not possible at that time?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions