1

I'm importing types from lowdb via @types/lowdb, and when using their mixins() method to configure mixins on a store, it complains that the argument I'm passing doesn't type-match:

Argument of type 'Map<string, Function>' is not assignable to parameter of type 'Dictionary<(...args: any[]) => any>'. Index signature is missing in type 'Map<string, Function>'.ts(2345)

I assumed that the type accepted by the mixins method was essentially a map of functions indexed with a string. So figured that Map<string, function> would be an acceptable thing to pass it. The context:

async setupStore ({storeName, storeMixins} : {storeName: string, storeMixins: Map<string, Function>}) {

    const store: LowdbSync<any> = await lowdb(new StoreMemoryAdapter(storeName))

    store._.mixin(storeMixins)

}

I guess my confusion here is a lack of understanding of what Dictionary<(...args: any[]) => any> expects in real terms. I'm unable to use the type declaration myself as it is not available to me in userland. But perhaps Map<string, Function> is not the correct equivalent?

shennan
  • 10,798
  • 5
  • 44
  • 79
  • Please provide `Dictionary` type – captain-yossarian from Ukraine Aug 09 '21 at 12:04
  • I don't see a definition of the `Dictionary` interface. I assume this is a type declared by the `@types/lowdb` library which I have linked to. Looking at that repo I can't see any declaration of `Dictionary`, so perhaps it is brought in via `@types/lodash` which is a dependency. How does one go about finding definitions of these things easily? – shennan Aug 09 '21 at 12:09
  • Try `Recordany>` or `{ [prop:string]:(...args:any[])=>any }` instead of `Map` because `Map` is not indexed. Btw try to avoid constructor types like `Function, String etc ...` Please let me know if it helped – captain-yossarian from Ukraine Aug 09 '21 at 12:18
  • 1
    This seems to work but I'm not sure as to why. Could you elaborate in a proper answer, and include how you were able to determine that `Dictionary` would be equivalent to what you've put? – shennan Aug 09 '21 at 12:22

1 Answers1

0

The error message is most important here:

Index signature is missing in type 'Map<string, Function>'.ts(2345)

More information about index signatures you can find in the docs

Let's take a look on Map type definition:

interface Map<K, V> {
    clear(): void;
    delete(key: K): boolean;
    forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
    get(key: K): V | undefined;
    has(key: K): boolean;
    set(key: K, value: V): this;
    readonly size: number;
}

As you might have noticed there is no index signature {[prop: string]:any}

This means that it is impossible to do smtg like this: Map<string, string>[string]. COnsider this example:

type Fn = (...args: any[]) => any

type A = Map<string, Fn>[string] // error
type B = Record<string, Fn>[string] // ok -> Fn

interface C {
  [prop: string]: Fn
}

type Cc = C[string] // ok -> Fn

Btw, there is a small difference between types an interfaces in context of indexing. Please see this answer.

  • So I could potentially pass `{ [prop: string]: any }` also? Or `{ [index: string]: (...args: any[]) => any }` if I wanted to be more specific about the function signature? I.e `Record` is a convenience type for the above? – shennan Aug 09 '21 at 12:39
  • Correct. But instead of `{ [prop: string]: any }` it is safer to use `Record` – captain-yossarian from Ukraine Aug 09 '21 at 12:40