DEV Community

Discussion on: The Trouble with TypeScript

Collapse
 
jwp profile image
John Peters • Edited

And then you hit a place where you need to pass in different objects. Your first thought is loosening up the definition but then you see an example with generics and realize TypeScript uses generics way more liberally than you are used to with C++ or Java. Even cooler, their type can often be inferred which means you don't even need to annotate and everything magically works.

That is until you add a few extra levels on to, and you start coming across the inconsistencies, or the places where types can't be inferred. The other day I was helping my lead dev work through some typings on factory function that produces hooks that return CSS in JS generated classes that are a result of the style definition passed into the factory and props passed into the hook. He had something very basic and couldn't quite figure out why his types weren't working. So I sat down and started using generics to assign multiple values and creating wrappers to project types for return values. Someone how after a couple of tries I got it working for the most part. I admit I felt pretty good about myself, but the developer looked bewildered. You see he thought he was finally getting TypeScript and he had no idea what I had just done. So I spent the next half an hour explaining it. In the end, he got it, but he still didn't feel any better about it as he would have never thought about it that way. And truthfully I was in the same boat months earlier.

This is more about lack of knowledge than the goodness of Typescript.

Besides, Typescript does not preclude anything that can be done in Javascript. If it can be done in Javascript it can be done in Typescript.

Javascript's cohersion makes for programmers who are clueless to the pitfalls of type cohersion. So much so, they don't see any value to static typing at all. Including pre compile time errors they call noise.

Choosing generics over spread operators or 'any' types, or optional properties is a design decision, not a language fault. Introducing generics to newbies is costly because they will never 'just get it'. Especially when the mentor writes articles about his dislike of Typescript.

Collapse
 
markerikson profile image
Mark Erikson

If it can be done in Javascript it can be done in Typescript.

I'd have to disagree with this statement.

There's a lot of very dynamic JS behavior that is difficult or effectively impossible to describe in TS. Try looking at the React-Redux type definitions as an example.

TS definitely pushes you to alter how your APIs are defined in order to get more easily typeable code. In some ways, this is actually a good thing, but just saying "you can do any JS in TS" is too much of a hand-wave-y statement.

Collapse
 
jwp profile image
John Peters

The only difference in a strong type and weak type is a definition file.

The worst case is to create a type of 'any' if needed; however the Typescript definition project has 95% coverage. Not a problem for me, really.

I have yet to be stopped from using any Javascript npm package. So not sure how valid this argument is...

Collapse
 
jwp profile image
John Peters

Excellent article on your experience with generics in Typescript. I concur that's some ugly stuff.

Collapse
 
brense profile image
Rense Bakker

The real point is... Defining types is optional in Typescript.
If you want to do it exactly right, yes some javascript behavior is hard to write types for, but whether you do that or not is a choice. Nothing in Typescript forces you to write types. You can literally grab a .js file, change the extension to .ts and run it through tsc...

Collapse
 
jwp profile image
John Peters

Yes those definitions are very complex; too complex, and most likely an indication of a bad design.

I've looked into redux before and rejected the concept of separation of state concerns to other components.

The MVVM pattern kept state in the view model and there were no state issues in past 20 years. State concerns do not need to be farmed out.

Thread Thread
 
markerikson profile image
Mark Erikson

My point had nothing to do with whether Redux is a tool you should use or not.

I'm simply saying that connect is a highly dynamic JS API that was designed before TS became popular. It accepts multiple arguments, all of which are optional, the first two arguments have multiple possible overload forms, and the result is a React "higher order component" that passes those derived props to your own component. It's a very JS-centric API. Thus, trying to define typedefs for that dynamic behavior becomes harder.

In contrast, our new React-Redux hooks API is two functions:

const dispatch = useDispatch();

const todo = useSelector( (state: RootState) => state.todos[props.id]);

We didn't specifically design them that way just to work better with TypeScript, but the ability to type them easily was a factor in our consideration.

So, as I said: there is some JS behavior that is extremely hard or impossible to type correctly in TS. Therefore, TS usage pushes you to design APIs that are easier to type.

Thread Thread
 
jwp profile image
John Peters

I have seen C# apis, where one endpoint served many different things. All were later ripped out as the 'SRP' Principal was a better pattern.

I'm simply saying that connect is a highly dynamic JS API that was designed before TS became popular

I was only noticing the 'less than optimal' design of allowing an interface to accept dynamic parms. Of course it's only an opinion.