Some tips:
- In JavaScript/TypeScript, don't use
==
and !=
when you want to mean strict equality or inequality; instead, do ===
and !==
, otherwise the language perfoms a looser comparison (e.g. 4 == '4'
is true
, while 4 === '4'
is false
).
- To check if something is an
Array
, the more idiomatic solution is Array.isArray(obj)
.
- Try to avoid using
arguments
. It's considered bad practice and deprecated in practice, and some times not accessible at all. Using the rest parameter is usually better (safer, easier) to use.
- To convert
number
to string
, prefer the .toString()
method, which ensures that it's actually a proper value and errors when empty.
- No need to use
$
or any fancy dependency for something like each()
; array.forEach()
should be well supported in browsers by now.
With all of that said, an opinionated rewrite of your code would be:
const formatString = (sTemplate: string, ...params: Array<string | number>) => {
params.forEach((value, index) => {
const newValue = typeof value === 'string' ? value : value.toString(10);
sTemplate = sTemplate.replace(new RegExp("\\{" + index + "\\}", "g"), newValue);
});
return sTemplate;
};
formatString("User {0} logged in", 'John');
formatString("Max {0} words allowed", 128.8999);
formatString("Form {0} to {1}", 10, 100);
Notice additional params
being allowed, rather than an array. While you can achieve what you have in your message (either a single param, or an array of params), I think it would be a bit non-idiomatic and likely to cause confusion.
In my above case, you can still pass an array as a parameter (if, say, it's generated somewhere else) by using an array spread like so:
const nums = [10, 100];
formatString("Form {0} to {1}", ...nums);
If you want to keep your original syntax, however, you can use it like this:
const formatString = (sTemplate: string, params?: Array<string | number> | string | number) => {
if (params !== undefined) {
const newParams = Array.isArray(params) ? params : [params];
newParams.forEach((value, index) => {
const newValue = typeof value === 'string' ? value : value.toString(10);
sTemplate = sTemplate.replace(new RegExp("\\{" + index + "\\}", "g"), newValue);
});
}
return sTemplate;
};
formatString("User {0} logged in", 'John');
formatString("Max {0} words allowed", 128.8999);
formatString("Form {0} to {1}", [10, 100]);
formatString("No params");
But one additional caveat is that you can't use undefined
as an actual parameter if if it's a single parameter; it'll assume it's not there and not perform the replacement in the template.
Good luck on your learning journey! JavaScript is a language that has some gotchas like the ==
/!=
case mentioned above, but TypeScript certainly makes it easier to get to valid, safe code, so I would recommend staying in that path!