5

I'm trying to write a definition file for the server-side API of ArangoDB. This API exposes a db object that can be used to access the collections, but also perform database-level operations like running queries. So I can call:

db['my-collection'] <- returns a collection object

but also:

db._query('some query') <- returns a query cursor

So I tried the following interface:

interface ArangoDatabase {
    [collectionName: string]: ArangoCollection;
    _query(query: string): ArangoCursor;
}

but that doesn't look valid to TS as it generates the following error:

Property '_query' of type '(query: string) => ArangoCursor' is not assignable to string index type 'ArangoCollection'.

Note: I tried this solution by giving the indexer a type of ArangoCollection|ArangoCursor but it didn't help.

Am I hitting a limit of what can be modelled with an interface, or is there another way around?

Thanks in advance.

Community
  • 1
  • 1
ThomasWeiss
  • 1,292
  • 16
  • 30

2 Answers2

10

You want to use intersection types. Try this:

interface ArangoDatabaseIndex {
  [collectionName: string]: ArangoCollection;
}
interface ArangoDatabaseQuery {
  _query(query: string): ArangoCursor;
}

type ArangoDatabase = ArangoDatabaseIndex & ArangoDatabaseQuery;
Aviad Hadad
  • 1,717
  • 12
  • 15
4

Type of query member is (query: string)=>ArangoCursor, that's why ArangoCollection|ArangoCursor union didn't work for you.

It should be:

interface ArangoDatabase {
    [collectionName: string]: ArangoCollection|((query: string)=>ArangoCursor);
    _query(query: string): ArangoCursor;
}
Aleksey L.
  • 35,047
  • 10
  • 74
  • 84