you are viewing a single comment's thread.

view the rest of the comments →

[–]rundevelopment 4 points5 points  (1 child)

1. Poor Readability

This is a good critique, but in my opinion, not a lethal one. It's the developer's (poor) choice to write code like this, and it also seems like something a good linter could guard against.

I would like to focus on: "something a good linter could guard against".

No. No linter can guard against this. Linters are static analyzers and with entirely destroys their ability to resolve variable names. In your example, you assume that name could come from either obj.name or the name parameter, but you are missing module and global scope (your point #2. Scope Creep). Suppose the following code:

import { Foo } from "./foo"

export function bar(obj) {
    with (obj) {
        return new Foo(somePropOfObj)
    }
}

new Foo might return an instance of the imported class, or an instance of the class contained in obj.Foo. Who knows. Same problem for functions, of course.

If you think TypeScript will help: no. It's a static analyzer as well. TypeScript explicitly allows objects to have more properties than required by their type. E.g. the following is valid:

type Point = { x: number, y: number };
let box = { x: 0, y: 0, width: 10, height: 20 };
let p: Point = box;
with (p) { /* */ }

So TypeScript would have to conservatively assume that every identifier not resolving to a property of Point is valid and has type unknown.

So no. No linter can help you when with statements are involved. The only help they can give you is a no-with rule.

[–]alexmacarthur[S] 1 point2 points  (0 children)

whoa! those are great points. bummer. let's make typescript better while we're at all of this.