The common misconception about TypeScript I hear a lot is - TypeScript is more OOP than JavaScript, TypeScript is more like Java, C#, was made for OOP programmers, it emphasizes classes and inheritance.
One of the last examples of such misconception being shared was part of quite popular article - TypeScript Tutorial: A step-by-step guide to learn TypeScript. Below quote from the article
TypesScript is an Object oriented programming language whereas JavaScript is a scripting language
Such a false statement in one of the most popular articles in dev.to about TypeScript 😔 . I decided to try to fight 💪 with these statements, and show you that TS is not in any bit more object oriented than JS itself.
TS has classes and inheritance so it's more OOP
TypeScript has classes, but JavaScript also has them. Take a look
// JS🟨
class User {
#name
constructor(name) {
this.#name = name;
}
}
const user = new User('Tom');
The same part in TS
// TS🟦
class User {
#name: string
constructor(name: string) {
this.#name = name;
}
}
const user = new User('Tom')
Any difference from additional type annotations? Don’t think so. Have you spotted private fields? Yes they are in both, as private fields went to stage 3 of ECMAScript standard.
Inheritance
There for both, consider
// JS🟨 and TS🟦
class Admin extends User{
#type = 'admin'
}
const admin = new Admin('Tom');
What is TS version of the above? The same… yes thanks to type inference I don’t need to change a bit. Where is the difference then? There is none
TypeScript type system emphasize OOP
That is true that TS has concept of interface, concept familiar for people working with statically typed object oriented languages like Java or C#. But TypeScript also has alternative syntax for types, and it's typical for functional languages, it is based on algebraic data types.
Instead of using interface and extends
interface X extends Y {x: number}
you can use type and intersection operator &
type X = Y & {x: number}
And you get the same result!
Check out below two equivalent versions of the same types definition
{
// interface version - familiar for Java/C#
interface User {
type: string
name: string
}
interface Admin extends User {
type: 'admin'
}
interface Moderator extends User {
type: 'mod'
}
function test(u: User) {
return u;
}
const admin: Admin = {
type: 'admin',
name: 'Tom'
}
test(admin) // admin can be used as user
}
{
// algebraic types version - familiar for functional programmers Haskell, Elm
type User = {
type: string
name: string
}
type Admin = User & {
type: 'admin'
}
type Moderator = User & {
type: 'mod'
}
function test(u: User) {
return u;
}
const admin: Admin = {
type: 'admin',
name: 'Tom'
}
test(admin) // admin can be used as user
}
You don’t need to use any interfaces in TS, you can do everything by type and type operators like intersection and union. Yes really!
Note Did you know that original idea of object oriented programming had nothing about inheritance. Alan Kay who had made this term was focusing on encapsulation and message passing.
Functional programming in TypeScript is hard
This last one is outside of the original argument, but if not OOP, then natural choice is Functional programming, so if we resign from classes we will most probably write functions and data transformations in the functional style.
Is then functional programming harder in TS than in JS? Yes it is slightly, but fortunately there are tools for that, most famous functional libraries for JS are fully typed, so if you use for example Ramda, there are types for it. Also there are specially made libraries for TS like fp-ts, which represent pure statically functional languages type constructs and utilities. So yes, we can go fully functional!
Note With newest feature of TS 4.0 - variadic tuple types, FP is slightly simpler to model!
From where then the misconception came from?
Probably there are few sources
- TS creator is the same person who made C#
- TS had classes and private fields before JS
- Type notation (interfaces, generics) looks like in Java, C#
First is rather wrong, as a person who made one language no needs to make other languages the same. Second is only historically true, but we have 2020, don’t we? Third is only about grammar, yes looks similar but it has nothing if the language is object oriented or not.
And to be clear TypeScript is object oriented language, but object orientation is not in any way better than in JavaScript itself. Historically that was true, as TS introduced classes, private fields and inheritance when there was no such equivalent in JS. But now it is not true, everything related to object orientation exists in JS, TypeScript only adds type level to it.
TypeScript is JavaScript with additional static types level, both are multi-paradigm programming languages. Next time if somebody will tell you TS is only for OOP, tell him that it's nothing more than a lie.
Latest comments (34)
ts is oop language though
Title ...
... then In article body:
In my view this statement undermines the title. I would also observe that slightly is an understatement. Functional style TypeScript requires a much better grasp of TypeScript's typing meta-language - to a degree that isn't usually necessary when practicing a class-based object-oriented style (example: Learn Advanced TypeScript).
Once we accept that in TypeScript the class-based object-oriented style is the path of least resistance (according to: "make the right thing easy and the wrong thing hard") I think it is fair to say that TypeScript skews the choice of implementation towards class-based object-orientation much more than JavaScript does.
In Dependency Injection revisited (2018) (Blog post) Mark Seeman juxtaposes F# code against the somewhat equivalent C# code which looks like a verbose mess. Functional-style TypeScript is often reminiscent of that C# mess.
So I don't think that stating that TypeScript favours class-based object-orientation a lot more than JavaScript is too far off the mark. It takes a lot more determination to pursue a functional style in TypeScript than it does in JavaScript.
What's more insidious about this is that TypeScript's perceived OO-ness over JavaScript is taken by the mainstream as further corroboration that class-based object-orientation is the "true software development paradigm" - even when there are hints that we're moving away from OO.
Original object-orientation dates back to Simula (1962) and Simula 67 had classes and inheritance - i.e. it was class-based. Alan Kay's statement was made in 1998, some 30 years later and identifies Carl Hewitt's Actor Model as his mental model. At OOPSLA '97 he was quoted as saying: "I made up the term 'object-oriented', and I can tell you I didn't have C++ in mind" - but it's unclear whether he actually originated the term.
The big issue is that the mainstream currently uses "object-oriented" when they are actually talking about "class-oriented" - i.e. classes being used exclusively to create objects.
However you can work with objects without needing classes:
and considering:
... so class-based object-orientation seems to have always been TypeScript's primary priority.
More to the point with TypeScript you are confined to practicing Guerilla-FP because TypeScript is sanctioned while other more suitable but niche statically typed functional to-JS transpilers are not:
Thanks for mentioning the history. I already mentioned that originally TS had classes earlier than JS had them, that is true. Also I don't see a big difference between using class-based and not classed based OOP. Class is just definition of some class of objects, you can make it by closure sure, but fundamentally there is no difference, as OOP is mostly about encapsulation, and this is Kay way of thinking. The second school teaches that OOP is about inheritance and classes, and this goes from C++ and Stroustrup. I will not argue about definition here.
This article was showing that the same OOP you can do in JS and in TS, so how you can state that TS is more object oriented if there is no real difference? Latest years shows that TS is going more into FP because that is what community demands. You can write TS without any class, and as I mentioned I am doing that successfully many years. I said FP is little harder as FP in JS has dynamic origins, it is based on LISP. Adding types to that is not easy task, but I think TS made a great progress with that.
Also about your last two links, it has nothing to TS, you can do function based OOP in TS. But why? I don't see a point in trying to avoid classes if you do OOP, I mean the only reason to avoid them is more like allergy after being too much exposed to Java. Creating objects by constructors being simple function is ok, but in the end of the day we achieve the same result. Even more "class" is just syntax sugar over setting prototype, yes the famous JS prototype which nobody wanted to use.
I have nothing against doing OOP without classes, but saying that it is something better is overstatement, they are two sides of the same coin.
And also pay attention I didn't write article "TypeScript the FP language", and this is what you are trying to argue with. I said that TS is multi-paradigm as JS is.
In class-based languages the object's "membership" is static - i.e. an object cannot change "classes" during it's lifetime. In JavaScript an object's capabilities can be augmented after construction - effectively changing its "class".
DCI (Data Context Interaction) for example needs objects to dynamically present roles while not changing their identity. Static class membership of mainstream class-based OO languages gets in the way, requiring workarounds. This lead to trygve.
So whether or not you see "lifetime class membership" as a feature for objects depends on your particular needs.
Erlang (and independently the Actor model) uses a shared-nothing asynchronous message passing system. So data-hiding isn't an objective but simply the result of sharing nothing.
Other than that many FP languages don't care about data-hiding but simply respect the notion of a opaque data type when necessary. As Rich Hickey observed:
"And if you have a notion of “private”, you need corresponding notions of privilege and trust. And that adds a whole ton of complexity and little value, creates rigidity in a system, and often forces things to live in places they shouldn’t."
So encapsulation may not be as desirable in all contexts, possibly not even in most.
By taking the position that TS makes a functional style harder to practice compared to an object-oriented style. Just because it doesn't stop determined individuals doesn't weaken the claim. Typing OO code in TypeScript is fundamentally easier than typing functional code (which is also less awkward to type in a dedicated FP language). Given that JavaScript isn't statically typed it doesn't discriminate either way.
In a world with TypeScript but without JavaScript I doubt something like JavaScript Allongé would have ever been written.
TypeScript's priority was to type JavaScript's imperative aspects - so the later additions feel bolted on and awkward.
I didn't imply it was better. Some would say it is better because it eliminates inheritance, forcing the use of composition. The point is that there are different ways of practicing object-orientation - class-based is just one of them. JavaScript's OO was inspired by Self.
Great Article !
Just avoid using classes whenever possible in your JavaScript code and everything will be fine ;-)
JavaScript is an OOP language because it answers to the principles that define a language as OOP: d.umn.edu/~gshute/softeng/presenta...
but what about any
functionor JS literal is indeed an object? OOP is not about private, public, protected fields, or inheritance implemented with interfaces, abstract classes, or whatever.from a point of view your examples are OOP as well.
Yes they are. But the article is not about what means OOP, or about every element of it in JS, it's about the bit where the misconception came from
I think this article is a bit misleading then. There's nothing wrong with saying Typescript is OOP and there's nothing wrong with saying Typescript is FP, what it is really wrong from the quoted statement is:
«TypesScript is an Object oriented programming language whereas JavaScript is a scripting language»
This is not a false statement, this is a misconstrued statement. For starters what's a scripting paradigm? What kind of paradigm is that? OOP is a paradigm, not a language, Java is a language that implements OOP paradigm, C is a language that implements imperative paradigm. But none of them implement pure paradigms, for example it's not possible (or rather feasible) to implement OOP paradigm without imperative paradigm (look at C++) as much as it's not possible to introduce FP without OOP after more than 30 years of OOP programming.
Then the question is: is Javascript OOP? Yes it is implemented with prototyping. So again I think in my humble opinion the statement is wrong about Javascript, not about Typescript.
The statement is horrible. Both parts are wrong, as it's has vs form. This is OOP and this is not. Scripting is totally different thing than paradigm.
But to be clear it's only example. There are in the community all the time such opinions that TS is only for OOP, like you want OOP you don't use JS but TS. But truth is you want static type system you choose TS, it has nothing to do if you will do OOP or not.
The mainstream of developers sees OOP as classes and interfaces, as both ale in TS from beginning then TS is by many considered more OOP.
Fact is that OOP is not about only classes but about message passing, but I focused on the differences in class based OOP as this is always the main point.
Js is multi-paradigm and TS follows that.
Classes don't mean OOP. JS was OO before it had classes, using prototypes and constructor functions. But people didn't know how to use it as it was too different.
This article just continues building on misconceptions.
O agree with you that classes are not needed to do OOP. But this is how mainstream sees OOP, and unfortunately the same look at things have tc39 as they made them a way to the language.
Purpose of this article was not to describe what is or not OOP but decline any OOP differences between TS and JS
Try Nim lang for Functional Immutable OOP and better Types than Typescript and powerful Metaprogramming.
github.com/nim-lang/Nim/wiki/Nim-f...
Great article! Hope many people get to read this.
The project that I'm currently working on is in TypeScript and it uses classes and functions alongside each other which works best for us. Using classes is a very good way to introduce dependency injection and make testability of complex components easier. But wherever possible we try to use simple pure functions.
Being extremely cautious with inheritance and try to avoid it in the majority of the cases.
I would love to read about using TS without classes and with fp approach. So far, even docs are pushing classes as the way to go and I'm reluctant to TS because of that.
We write many thousands of lines of TS code and, at least on the back end, we don't use the class keyword except in very rare cases where the class will be a singleton instance.
We don't go as far as using FP libraries and trying to do full FP, however we write all pure functions where possible, and use a few other really useful FP techniques to make code easy to write, test, and maintain.
We write OOP in the truest sense of the term, because we use objects and message passing, but we don't write anything like what most people consider OOP. The tight coupling with class inheritance is just terrible.
In any case, TS is not an OOP language. Most languages don't push you into a single paradigm and TS is no different.
I'm also not sure why people think FP is harder with TS than JS. There are generics which help with some of the problems I've seen listed.
Thanks for this comment. That is great. But about why it is harder, grab this code from Ramda
pipetypes:Like this type? Take them more here - Ramda types 😉
🤣
Its natural that docs of TS will also mention about classes as TS is multi-paradigm language and you can write OOP in the same way you can in JS. But there are also function typings, higher order functions support and so on, in official TS docs you have section how to type functions - handbook