TSLint rules for Lodash
0.0.1
release, so buyer beware.
Motivation
get-check-undefined
:
Due to the changes in how Lodash's TS types (via
@types/lodash), and the inherent complexity in defining
good types for lodash.get
return values, I see the following pattern a
lot in code-reviews:
const someObject: string = lodash.get(mainObject, 'some.complicated.path.traversal')
// ...after some more lines of code
const itemLength = someObject.length; // 💥 at runtime, fine at compile time!
In most cases, the programmer who wrote this wanted to use get
just to
have a safe-traversal on a complex object, but didn't bother to add a
default value, perhaps because they were checking for nulls somewhere
down the line.
However, this particular line causes subtle bugs in practice. The
right-side computation can return undefined
if the path in the object
doesn't exist, even perhaps due to a typo (not all that uncommon). Until
at-least typescript 3.5breaking-changes, due to the way the
@types/lodash
types are defined, the return type of get
when no
default parameter (third argument to the call) is specified is set to
any
lodash-type-any. Due to this, and since we specified the variable
value to be a string
type, we've potentially masked the case when the
right-side call returns undefined
^1.
It's kind of ironic that without TS, that line would've been checked during code-reviews thoroughly. Having TS in the codebase kind of gives a sense of security, and in this case, it ends up providing a false sense of security.
I can't review all the PRs that are opened in our project. So I decided to automate this.
How it works
0.0.1.beta.
version, this plugin looks for any function calls
that are lodash.get
or get
, and checks the following:
- Is it being assigned to a variable?
- If so, does it have
| undefined
in its type definition.
If these two cases match, that line will be marked as an error.
Roadmap
- Add metadata property and specify description
- Add better check for whether the
get
function is actually from lodash. This could either be done by providing a configuration option listing out regexes, and/or by scanning imports. - Add tests
Installation
npm install @kgrz/tslint-lodash@beta
Configuration
In your project's tslint.json
, add the following:
{
"extends": [
"@kgrz/tslint-lodash"
],
"rules": {
"get-check-undefined": true
}
}
^1: It's kind of interesting to note that in TypeScript 3.5 and above,
these any
types get auto-converted as unknown
type, kind of fixing
the problem. unknown
cannot be converted to a string
, and will throw
an error.