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 badges2 Answers
Reset to default 13The 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.