最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeScript with Lodash: _.map(["123", " 234 "], _.trim) returns boolean[]? - St

programmeradmin1浏览0评论

I have an array of strings which have been split like so:

var searchValue = "600-800, 123, 180";
var groups = searchValue.split(","); // => ["600-800", " 123", " 180"]

(so there is potentially whitespace around the items) and I would like to remove the whitespace. I know that I can use Array.prototype.map with String.prototype.trim, but I would like a solution specifically using Lodash.

According to the docs, I should be able to say: _.map([' foo ', ' bar '], _.trim); and it will return ['foo', 'bar'], which is a string[].

However, TypeScript is barking at me. Here's what I'm seeing in my editor.

I am running TypeScript 2.3.2 and Lodash 4.17.4

Strangely enough, if I say:

var values:string[] = _.map([' foo ', ' bar '], String.prototype.trim);

The TypeScript errors go away, but I get the following runtime error when searchValue is empty, and groups returns [""]:

TypeError: String.prototype.trim called on null or undefined

Things I have tried:

var values:string[] = _.map(_.filter(groups, group => group.indexOf("-") === -1), _.trim);
var values:string[] = _.map(_.filter(groups, function (group) { return group.indexOf("-") === -1; }), _.trim);
var values:string[] = _.map<string, (string?: string, chars?: string) => string>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);
var values:string[] = _.map<string, (string?: string, chars?: string) => string[]>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);
var values:string[] = _.map<string, (string: string, chars: string) => string>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);
var values:string[] = _.map<string, (string: string) => string>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);

All to no avail. I am at a loss. Is there something I am doing wrong here or is this possibly a Lodash/TypeScript bug?

I have an array of strings which have been split like so:

var searchValue = "600-800, 123, 180";
var groups = searchValue.split(","); // => ["600-800", " 123", " 180"]

(so there is potentially whitespace around the items) and I would like to remove the whitespace. I know that I can use Array.prototype.map with String.prototype.trim, but I would like a solution specifically using Lodash.

According to the docs, I should be able to say: _.map([' foo ', ' bar '], _.trim); and it will return ['foo', 'bar'], which is a string[].

However, TypeScript is barking at me. Here's what I'm seeing in my editor.

I am running TypeScript 2.3.2 and Lodash 4.17.4

Strangely enough, if I say:

var values:string[] = _.map([' foo ', ' bar '], String.prototype.trim);

The TypeScript errors go away, but I get the following runtime error when searchValue is empty, and groups returns [""]:

TypeError: String.prototype.trim called on null or undefined

Things I have tried:

var values:string[] = _.map(_.filter(groups, group => group.indexOf("-") === -1), _.trim);
var values:string[] = _.map(_.filter(groups, function (group) { return group.indexOf("-") === -1; }), _.trim);
var values:string[] = _.map<string, (string?: string, chars?: string) => string>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);
var values:string[] = _.map<string, (string?: string, chars?: string) => string[]>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);
var values:string[] = _.map<string, (string: string, chars: string) => string>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);
var values:string[] = _.map<string, (string: string) => string>(_.filter(groups, function (group) { return group.indexOf("-") === -1 }), _.trim);

All to no avail. I am at a loss. Is there something I am doing wrong here or is this possibly a Lodash/TypeScript bug?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jun 9, 2017 at 23:06 mhodgesmhodges 11.1k2 gold badges31 silver badges48 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 13

The following variation seems to work:

let values: string[] = _.map(['  foo  ', '  bar  '], str => _.trim(str))

Here's my guess as to why this is happening. There are many overloads for map, and you want to target this one:

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

where ListIterator is defined as:

type ListIterator<T, TResult> = (value: T, index: number, collection: List<T>) => TResult;

Thus you want the trimming function to match the above definition for ListIterator. But trim is actually defined as:

trim(
    string?: string,
    chars?: string
): string;

So when you do the following:

let values: string[] = _.map(['  foo  ', '  bar  '], _.trim);

You actually end up hitting a different overload, which is defined as:

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

So when you switch to the following variation:

let values: string[] = _.map(['  foo  ', '  bar  '], str => _.trim(str))

Your trimming function str => _trim(str) conforms to ListIterator, even though it leaves out the last 2 parameters (index and collection).

The problem is that _.trim can take two arguments:

trim(string?: string, chars?: string): string;

Which is incompatible with lodash's ListIterator type, in which the second argument, if present, is a number (the index).

Thus the compiler is falling back to a different typing for the _.map function, an obscure one which takes an object as the iteratee and returns an array of booleans ("returns true for elements that the properties of the given object, else false.")

Frank Modica's answer gives the correct solution.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论