Hacker Newsnew | past | comments | ask | show | jobs | submit | qwer's commentslogin

> I'm confused how people can advocate TDD and not like static types too seeing as static typing gives you robust automated tests for the minimal cost of adding type annotations every now and then.

For me personally as a TDD person, I just don't care about testing types. I test values. The type-checker just doesn't do much that I actually care about (better in-editor support is nice though). I know it's not a fashionable answer these days, but for me it's true. I don't see the pay-off in doing both, and types alone are not enough.


I don't know where this misconception started, but you can't just run javascript through a typescript compiler. There is a huge amount of valid javascript that is not valid typescript. Try something like `const testVar = {}; testVar.asdf = "asdf";`. Node web frameworks, for example, are based entirely off this ability to monkey-patch the request object.


I think grandparent was referring to the fact that you can tell the compiler to ignore type errors if you so choose. The TypeScript compiler is perfectly happy to compile the code in your example, if you disable strict type checking and treat type errors as warnings. On top of that, there are simple annotations you can add that let you silence warnings as they come up, e.g. `const testVar: any = {}; testVar.asdf = "asdf";`. This is not too far off from a linter with comments to disable linting when you don't want it. So yes, technically, you can just run JavaScript through a TypeScript compiler.


Sure... I guess you're saying that you can use the typescript compiler just fine as long as you turn off literally the only reason for it?

Have you been on a team that adequately managed a list of thousands of warnings, always finding and fixing just the ones that are "important"?


Yes. As a matter of fact, I'm currently working on a large JS codebase that is a decade old. We switched over all the code to TypeScript in one go, and we are gradually fixing the type errors over time. VSCode does an excellent job of showing you type annotations and type errors inline, so the typing is very useful even if you have thousands of errors elsewhere in the project and never even run the type checker globally.

In fact, out of the dozen or so TS codebases I've worked on, I've rarely seen one completely free of type errors. And yet no team has ever doubted the value of the type system. It's a very pragmatic approach which works very well for many teams in my experience.


I just finished something similar: http://caines.ca/blog/2018/12/11/a-javascript-to-typescript-...

We opted to keep it strict (no implicit `any`) through the entire transition but only apply it to ts files, so we are indeed completely free of type errors now. We only have 50 cases of (explicit) `any` in 85K+ LOC and they're in type def files.

Let me be the first person you've met to doubt the value of the type system. I do like the in-editor support, but you pay for it with about 25% more code.

I'm certainly not advocating undoing it, but I personally wouldn't do it again (though the team has mixed opinions).

Just curious: What's your test coverage like?


So how many errors were uncovered, and how serious could they have been?


It's in the blog post, but more were created by the transition than removed. There were less than 10 issues found and none were anything that users were concerned about.


The alternative is that the code exists but it has no warning to indicate the code smell. TS is clearly preferable to that. Further, you're wrong to suggest that blocking the code from running on type errors is "the only reason" for it. TS offers very nice autocomplete support that you can't get without it as well as jump to definition and yes, warnings.


Not advocating for this, but that's not too far off from how some C/C++ codebases work.


The compiler can most definitely type-check that code. It's up to you whether or not you want to ignore certain types errors. Want to ignore monkey-patching related errors? Filter out all lines from tsc that include TS2339.


I just wanted to say that I absolutely love the fact that tsc errors have codes, such as "TS2339".

This is a fundamental part of error handling and DX that, unfortunately, is left out 10 out of 10 in tooling, applications and libraries alike, in special opensource projects.


Front page of the TypeScript website:

"TypeScript is a typed superset of JavaScript..."

"Use existing JavaScript code, incorporate popular JavaScript libraries..."

You should be able to use --allowJs and have everything compile just fine, otherwise log a bug.


That's what the --allowJs flag is for.


I'm not sure exactly what you mean by "not valid" but that example is absolutely valid typescript, and will compile perfectly fine.


By default, you'll get "error TS2339: Property 'asdf' does not exist on type '{}'.". Yes, the error can be disabled.


Yes, some code requires ratcheting down strictness even from the defaults.


`const testVar = {}` doesn't mean that the object is immutable, it means that testVar will never point to something else.


He's not saying that TypeScript complains because he thinks TypeScript considers testVar immutable here. TypeScript will complain because it will infer the type of testVar is an object with no properties, and `testVar.asdf = "asdf";` is an attempt to write to a nonexistent property.


This sounds like an if-it-compiles-it-works argument.


Well don't lose sight of the goal. The goal is less bugs. Static typing is just for internal quality. Users don't give a rat's ass if your types are correct as long as the program works. Proof: Many wildly and massively successful programs are duck-typed.

Nobody ever cared to use tests to replicate what a type system does. That's a straw man. Tests go straight for the actual goal by testing actual values. Correct values are what are necessary. Types on the other hand are neither necessary nor sufficient.


"Static typing is just for internal quality."

Frankly, I don't even know what to do with such a statement. What is your definition of "internal" ?

I just did a very large re-factor of a codebase a few days ago where I changed a lot of event handler (method) types in a codebase of around 200K lines of code (Object Pascal). This means that the method signature of every single event handler could have been wrong in some way if I made a mistake, and it would have introduced a pretty egregious, non-internal bug in every case. How would you test such a massive change without replicating every single thing that a static type system and compiler already do for you ?


This has been my experience too. I've done a bunch of these sorts of changes over the years in C++. It's very straightforward: break code, fix errors, run code, fix remaining bugs (if there are any), commit code.

None of these projects had unit tests, but that's fine - you don't really need them for this sort of modification, just some patience, a tolerance for boredom (that, or the ability to suck it up anyway), and a complete lack of concern about messages such as 'ERROR: 0/1,577 file(s) built. NOTE: Error limit exceeded - only showing the first 99,999'.


Well let me first remind you that you're in a javascript thread. OO Pascal is strict enough that you're not going to get the opportunity to see things work when they get types that they didn't expect because the compiler is unforgiving. So that's going to be hard for you to imagine, but it happens in javascriptland. A function in javascript meant to take a number to output "X hours ago" could very easily get the string "3" and still do exactly what the user expects. That's what I mean by an incorrect type that is internal only, and not a user-facing bug. This is an overly simplified example too. With duck-typing you can often get away with all kinds of not-the-type-that-the-method-expected and live to tell the tale.

I haven't touched OO Pascal in 15 years, so I can't speak to how you would write tests for it, or if there's even a testing framework. I will tell you that I left the if-it-compiles-it-works attitude around that time too though.


Yes, I understand how JS works. My company markets and sells a web development IDE that includes an Object Pascal->JS compiler.

Re: your definition of "internal": I suspected that this was what you meant. I also disagree with this particular version of "correctness". If the developer intended that a particular function accept an integer, then accepting anything else is essentially a bug, and the fact that it works at all is down to pure coincidence.

As for writing tests in OP: you write tests in the same manner that you do with Java, C++, C#, etc.


Internal quality is external quality haha. If your types are wrong your program is wrong, and if it just happens to work now wait until more people use it, or you refactor it, or you change the way it works. Your users are basically just fuzzing machines haha.

Your statement that "nobody ever cared to use tests to replicate what the type system does" is trivially false, have you ever tested what happens when you pass "null" into a function that probably shouldn't take null? If so, you just did. Some type systems allow you to even specify valid subranges of types, and combined with algebraic data types, it's effectively impossible to misuse.


> If your types are wrong your program is wrong

That's not necessarily true though is it? If the "1" in the "1 hour ago" message in the header of your reply wasn't the expected type of the writer of the output function but ultimately still shows up as "1 hour ago" to the user, there's no user-facing defect. I can promise you that this happens all the time in javascript. You're in a thread about Javascript.

> have you ever tested what happens when you pass "null" into a function

Not that I recall. Javascript will throw an appropriate error when it detects that your duck isn't quacking correctly. No one writes validation logic everywhere on internal units, so there's no functionality to verify with a test.

With that said, null is decidedly not "just a type". It's also a value. I generally avoid using null everywhere as much as possible too, because it's a pretty terrible concept.

> Some type systems allow you to even specify valid subranges of types, and combined with algebraic data types, it's effectively impossible to misuse.

Sure but you're in a thread about javascript and typescript. And let's be honest: the vast majority of type systems do not support that.


> the easily observed phenomenon that some developers are 10x more productive than other developers.

How are you measuring? LOC? Semi-colons per hour? story points? If you're measuring in "dollars earned", how do you think their managers are measuring? And can they tell the difference between a 10x programmer and an 11x programmer?


Then clearly you've never met one.


Clearly... but then again I won't work at a place with any developers less than 11x.


I wouldn't have noticed if it hadn't been pointed out but it's definitely a term for a pretty outdated female-only position so I think the point isn't so extreme.

I can almost never detect this kind of stuff because it doesn't affect me directly and I'm sure the dev meant no ill-will, but once pointed out, I can see how projects named like this would get under people's skin.

"made, the MArkDown Executor"? :D It's pretty easy to be more inclusive.


The suffix "ake" is "standard" for these task runners... Cake (C#), Fake (F#) etc... So of course it should be called Make! ... ... wait ... ... shit ...


Just slowly go to bed earlier every day. Set your alarm for your go-to-bed time. Read a book if you can't sleep, but not on a bright-screened device.

I used to be such a nighthawk that I'd be waking up daily at 7 pm. Getting old naturally fixes that too.


In that scenario I bet they're even more effective without the condescending "manager" adding nothing.


I know this goes against the usual attitude about remote work around here but...

That flow-chart at the bottom is hilariously true. I've been a part of remote work as both a manager and an engineer, and this is exactly how it is because of different locations, the lo-fi aspect of existing remote collaboration tools, and the activation energy required to communicate more often (and if you're in different timezones, good luck to you!).

If you're an engineer that wants to really understand what you're trying to build and why, or if you want to be part of the problem-identification stage rather than just implementing someone's specs, this type of arrangement will drive you insane.

Some engineers are perfectly happy with a detailed spec though. For them, I completely understand the lure of remote work.


I think it's more nuanced than that and one can consistently hold both viewpoints at the same time. You just need to have the experience that a soa-first approach is even worse than the ball of mud.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: