In one of my recent PRs I changed all interfaces to types because there were already more types than interfaces. In the review, I was asked to reve...
For further actions, you may consider blocking this person and/or reporting abuse
type
s are actually aliasesOne of the sudden realizations I had about types and interfaces in TypeScript is that they're not actually "types", they're type aliases. As they don't define new types, they just they give them a new name.
In other words, they could have used the keyword
alias
instead oftype
and maybe saved some troubles.This means that interfaces are "opaque" relatively to its internal structure, whereas type aliases are not. I.e., the type hint you get is just
interface IAnimal
in the former case, and the whole type alias definition in the latter.Using
new
to define constructor signaturesMy suggestion here is that you're misunderstanding the role of interface that define constructor signatures. When you do
that is not an interface you should implement. That's a type to describe the class itself. For example:
This means that if you have static properties defined on a class, you can have them defined on an interface:
On the other hand, when you're using
implements
in a class, you're describing the shape of an instance of that class. Which means you writeclass Parrot implements IAnimal {...}
, becauseParrot
instances comply to the shape defined byIAnimal
.Edit: missed one of your replies in the comments that is actually on point on that 🙂
this is interesting. I saw it somewhere before but didn't pay attention, now I see what this was about.
But there is
Record<TAnimal, string>
for this.Interesting
Function overloading seems to work similar
One more thing: as I said interface allows extension even after declaration, so it would be possible extend interface exposed by 3-rd party library, but I can't imagine good use case for it. Any ideas?
There’s an example of the usefulness of this in a older than the current version of a functional programming library fp-ts.
It’s called declaration merging and it was used in that library, that implements higher kinded types, to extend those types.
Can you please point me to the code (link to the file/commit in github)? I want to understand it better
Yes, you can have a look here:
github.com/gcanti/fp-ts/tree/1.x
Has I explained this particular feature was used extensively in V1, but I think that is no longer the case due to the way the library is now structured.
An example where you'd want to extend the interface of a 3rd party API is OrderCloud. They have the property
xp
to enable you to extend their data model. Here's an example of a type wherexp
is object (I think sometimes it'sany
too).And the extension would be something like:
From TS docs:
“As we mentioned, type aliases can act sort of like interfaces; however, there are some subtle differences.
One difference is that interfaces create a new name that is used everywhere. Type aliases don’t create a new name — for instance, error messages won’t use the alias name. In the code below, hovering over interfaced in an editor will show that it returns an Interface, but will show that aliased returns object literal type.“
This is why we prefer interfaces. It makes everything more readable.
Type syntax seems archaic and obscure, Interfaces are more direct and explicit...clarity wins
they look the same?
replace
interface
withtype
add equal sign before{
→"=" is already odd, different from classes and all other non-object "{ ... }" statements.
Also, almost no non-advanced training material I can remember talks about "type"..
Running a Dev shop, why overload people's brains with something that looks archaic and has questionable use (at least for business applications)?
Also everyone has lots of historic interface/class/type/structure luggage from other languages that doesn't map into using types in place of interfaces.
I imagine there's valid use for it for dev tool creators.
You keep using term "archaic".
a) What is your reason behind it?
b) Why archaic is a bad thing? Math notation of plus is archaic, let's change the notation?
I feel like people who have background in Java, C# would be more comfortable with notation of interface.
People who have background in functional languages, like OCaml (all ML family?) will prefer type notation.
People who don't have background - will accept whatever you show them first.
Argument
"=" is already odd
is a matter of taste. And if you don't like it based on that, there is no reason for me to argue. There are people who prefer to put semicolons in the end of JS and who don't...I would be willing to bet that despite their different capabilities (types vs interfaces), people with an OOP background will be a bit biased towards interfaces while people with FP backgrounds will tend to prefer types.
I also disagree with this, I think for one an
interface
in the OO world conveys the message that somewhere you're going to have an implementation of sorts and when you don't have at least one of those that is not being explicit.I would also argue that an
interface
conveys the message of abstraction which is not the case when one would use it to define the structure of an object which atype
does a much better of.I think a
type
is very explicit in that sense.Also, you say that
type
is archaic, well, it's not, it is used in many other languages (modern languages) to represent exactly that.I had a similar experience, which led me to open a PR for the Typescript handbook, documenting using type aliases over interfaces.
github.com/microsoft/TypeScript-Ha...
In the new section, you wrote:
But it should be:
Doesn't seem to help typescriptlang.org/play/#code/JYOw... 🤔
I guess the only reasonable usage of
new
is this:code example from stackoverflow.com/questions/134070...
If you want to declare type of constructor you can do something like this:
Yes. I wasn't unable to check it, but I was sure I did something like that. But according to the docs
typescriptlang.org/docs/handbook/i...
Seems like you are right. Constructors interfaces declarations are mostly effective as function arguments.
I don't know all the answers, I simply experimented to write this post. It also can happen I miss a lot of things, or there are bugs in TS or some small details which I miss. All ideas are more than welcome. (TypeScript documentation seems to lag behind actual behavior sometimes)
Hey there! I shared your article here t.me/theprogrammersclub and check out the group if you haven't already!