简体   繁体   中英

Passing an object to ._map in typescript

Below is my class with static member config.

import {Injectable} from '@angular/core';
import {Config} from '../shared/interfaces'

export class GlobalData {

    static config:Config = {
        appName: "",
        line: "",
    }

    constructor(private app:PApplication){
        GlobalData.config.appName = app.getData().Style? 'P_APP' : 'P_WEB'
        GlobalData.config.line = 'PApp'
    }

}

Below is my interface Config

export interface Config {
    appName: string
    line: string
}

I am trying to pass my static config object to below function:

var appConfig = this.appConfig(GlobalData.config);

appConfig = (configVariable: Config) => {
    return _.map(configVariable, function(val, key) {
        return key + "=" + val;
    }).join("&");
}

I am getting the below error:

[ts] Argument of type 'Config' is not assignable to parameter of type 'List<{}> | Dictionary<{}> | NumericDictionary<{}>'. Type 'Config' is not assignable to type 'NumericDictionary<{}>'. Index signature is missing in type 'Config'.

Basically in Javascript , the config was a global object , which can be accessed in any controller/services .

var config = {appName: "", line: "" }

The definitions for the map function are :

map<T, TResult>(
    list: _.List<T>,
    iterator: _.ListIterator<T, TResult> | _.IterateePropertyShorthand | _.IterateeMatcherShorthand<any>,
    context?: any): TResult[];

map<T, TResult>(
    object: _.Dictionary<T>,
    iterator: _.ObjectIterator<T, TResult>,
    context?: any): TResult[];

As you can see, the passed object should be of types _.List<T> or _.Dictionary<T> .
In your case it needs to be _.Dictionary<T> , which is defined like so:

interface Dictionary<T> extends Collection<T> {
    [index: string]: T;
}

Your Config interface doesn't have an index signature which is why the compiler complains.
To get around that just cast it to any :

return _.map(configVariable as any, function(val, key) {
    return key + "=" + val;
}).join("&");

Edit

The signatures for map in lodash are similar:

map<T, TResult>(
    collection: List<T>,
    iteratee?: ListIterator<T, TResult>
): TResult[];

map<T extends {}, TResult>(
    collection: Dictionary<T>,
    iteratee?: DictionaryIterator<T, TResult>
): TResult[];

map<T extends {}, TResult>(
    collection: NumericDictionary<T>,
    iteratee?: NumericDictionaryIterator<T, TResult>
): TResult[];

map<T, TResult>(
    collection: List<T>|Dictionary<T>|NumericDictionary<T>,
    iteratee?: string
): TResult[];

map<T, TObject extends {}>(
    collection: List<T>|Dictionary<T>|NumericDictionary<T>,
    iteratee?: TObject
): boolean[];

The Dictionary is a bit different:

interface Dictionary<T> {
    [index: string]: T;
}

So it's the same problem.
As for avoiding using any , you can do:

interface Config extends _.Dictionary<string> {
    appName: string
    line: string
}

And then this:

return _.map(configVariable, function(val, key) {
    return key + "=" + val;
}).join("&");

Will compile with no errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM