Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create Map object with functions as values

I'm trying to create a Map object from a string,function dictionnary.

const entityTagDictionnary = [
  ['GRAPH_ADD_PROPERTY_SUBTYPE', (entity) => {
    console.log('addSubtype called!');
    return entity;
  }],
  ['GRAPH_IGNORE_PROPERTY_SENTENCE', (entity) => {
    console.log('ignore property called!');
    return entity;
  }],
  ['GRAPH_FORMAT_DATES', (entity) => {
    console.log('formatDates called!');
    return entity;
  }],
];

const entityMap : Map<string, Function> = new Map(entityTagDictionnary);

I've got the following error:

Argument of type '(string | ((entity: any) => any))[][]' isn't matching the argument 'Iterable<[string, Function]>'.

Am I doing anything wrong?

like image 890
Baptiste Arnaud Avatar asked Sep 01 '25 02:09

Baptiste Arnaud


1 Answers

The problem is that the constructor to map takes an array of tuples and infers the type based on the tuple type. The signature for this constructor is :

new <K, V>(entries?: ReadonlyArray<[K, V]>): Map<K, V>;

The problem with your array is that is is not an array of tuples, it's an array of arrays, an item of the inner array being string | ((e: any) => any). Typescript does not infer tuple types based on array literals unless it is required to do so. The simple solution is to put the array literal in the constructor argument:

const entityMap: Map<string, Function> = new Map([
    ['GRAPH_ADD_PROPERTY_SUBTYPE', (entity: any) => {
        console.log('addSubtype called!');
        return entity;
    }],
    ['GRAPH_IGNORE_PROPERTY_SENTENCE', (entity: any) => {
        console.log('ignore property called!');
        return entity;
    }],
    ['GRAPH_FORMAT_DATES', (entity: any) => {
        console.log('formatDates called!');
        return entity;
    }],
]);

Or use an explicit type annotation:

const entityTagDictionnary: Array<[string, (e: any)=> any]> = [...]

Or you can use a tuple helper function to force typescript to infer tuple types, as described here

function tupleArray<T1, T2, T3>(arr:[T1, T2, T3][]) : typeof arr 
function tupleArray<T1, T2>(arr:[T1, T2][]) : typeof arr 
function tupleArray<T1>(arr:[T1][]) : typeof arr 
function tupleArray(arr:any[]) : any[]{
    return arr;
}
const entityTagDictionnary = tupleArray([
]);
like image 73
Titian Cernicova-Dragomir Avatar answered Sep 02 '25 16:09

Titian Cernicova-Dragomir