News for hackers. Stuff that matters.
Re:TypeScript’s quirks: How inconsistencies make the languag... by kazinator on Saturday February 01, 2020 @03:08AM (#22209372)
If you can pass a Cat to a Dog function, where is the better checking?

That would be one of the hello-world test cases for a type checker bolted on to a dynamic language.

That type checker itself has introduced the syntax for declaring Cat and Dog classes; yet is neglecting to do the obvious with it.

Re:TypeScript’s quirks: How inconsistencies make the languag... by MaulingMonkey on Saturday February 01, 2020 @03:38AM (#22209480)
Note that you can only pass Cat to a Dog function if:

* All fields of Dog are also present in Cat, with compatible type signatures

* All functions of Dog are also present in Cat, with comaptible type signatures

"compatible type signatures" does seem to leave some suprising co/contravariance holes still when using wider union types, but C#/Java arrays also have co/contravariance holes and we don't automatically write off their entire type systems because of it. Or, well, at least I don't ;).

As a meaningless point of ancedata: Making these types sufficiently equivalent to fall through this type safety hole appears to be rare enough that I've never done so by accident - allowing me to be suprised by the article's example of passing a class Cat to a class Dog-accepting function being legal. While typescript has never been my primary dayjob, it's been a significant secondary part of my dayjob and hobby junk.

(EDIT: Minor clarifications)

Re:TypeScript’s quirks: How inconsistencies make the languag... by Kinrany on Saturday February 01, 2020 @06:45AM (#22210017)
Re:TypeScript’s quirks: How inconsistencies make the languag... by carlmr on Saturday February 01, 2020 @05:31AM (#22209803)
C# has a great type system, but everything has ToString() and sometimes that doesn't output something sensible, and gets implicitly converted, leading to garbage.

Still much better than working in C or some other weakly typed languages.

Re:TypeScript’s quirks: How inconsistencies make the languag... by paavohtl on Saturday February 01, 2020 @05:01AM (#22209713)
As a long time TypeScript user, I do think this is a design mistake with the language. For example, it breaks instanceof checks.

However:

- The language primarily uses structural typing. If two classes are compatible, it's not completely unreasonable to expect them to also behave in a structural way (though I would prefer them not to).

- Adding a private field to a class makes it work as a nominal type (https://michalzalecki.com/nominal-typing-in-typescript/#appr...). It feels a bit hacky and it's not very well documented, but you could argue that until a class has some private state you can't publicly access, there's no reason to prevent you from declaring a compatible class.

- From my experience idiomatic TypeScript rarely uses classes, the primary exception being React components. In teams I've been a part of we've always written TypeScript (and JavaScript) like an (impure) functional language, taking full advantage of ADTs, simple structurally typed data and more-or-less pure functions.

Re:TypeScript’s quirks: How inconsistencies make the languag... by The_rationalist on Saturday February 01, 2020 @08:44AM (#22210458)
taking full advantage of ADTs What? There is no clean way to switch on the types of an ADT on typescript, I believe.
Re:TypeScript’s quirks: How inconsistencies make the languag... by alexcole on Saturday February 01, 2020 @08:43PM (#22214584)
Well discriminated unions are TypeScript's implementation of ADTs (but whether they are "clean" is could be debated)
Re:TypeScript’s quirks: How inconsistencies make the languag... by meheleventyone on Saturday February 01, 2020 @03:55AM (#22209525)
The problem is less that the syntax exists and more that people are used to nominal typing so get confused with edge cases where structural typing departs from it. The type checker isn’t breaking any promises it made it’s just slightly different from people’s mental model of how types should work from experience of other languages.

It’s just a different kettle of fish to learn.

Re:TypeScript’s quirks: How inconsistencies make the languag... by DonHopkins on Saturday February 01, 2020 @07:07AM (#22210081)
CatDog typing sure looks, walks, and quacks a lot like Duck typing.

https://en.wikipedia.org/wiki/CatDog

https://en.wikipedia.org/wiki/Duck_typing

Re:TypeScript’s quirks: How inconsistencies make the languag... by redmorphium on Saturday February 01, 2020 @07:29AM (#22210165)
From your second link:

https://en.wikipedia.org/wiki/Duck_typing#Structural_type_sy...

> Duck typing is similar to, but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time.

Re:TypeScript’s quirks: How inconsistencies make the languag... by kazinator on Tuesday February 04, 2020 @12:21AM (#22232662)
That looks like ooks like "original research". It's obvious that what is described as dynamic-only duck typing could be statically checked. So that is to say, a given expression foo.bar in the program could be statically checked to make sure that all possible values that foo takes on have property bar. If three classes A, B, C in the program have property foo, then this means verifying that foo is A | B | C. Thus, "static duck typing".
Re:TypeScript’s quirks: How inconsistencies make the languag... by greenshackle2 on Saturday February 01, 2020 @12:25PM (#22211689)
Kind of but not really. If you ask a "duck" to quack, duck typing is satisfied with any object that implements the quack method.

With structural typing, the type system will check that the "duck" not only quacks but also looks like and walks like a duck, before it is allowed to be asked to quack.

EDIT: of course with small enough interfaces you can get structural typing pretty close to duck typing, if you have interfaces "QuacksLikeDuck", "WalksLikeDuck", "LooksLikeDuck", etc. instead of one big "Duck" interface.

Re:TypeScript’s quirks: How inconsistencies make the languag... by dtech on Saturday February 01, 2020 @05:11AM (#22209747)
> If you can pass a Cat to a Dog function, where is the better checking?

If you have compatible method, fields and types, in a duck-typed ecosystem like Javascript it is a major boon that it is possible to interchange them, because it happens all the time in the ecosystem.

The standard way to do enforce exactly the right interface in typescript if you need to is to add a `type: "cat" | "dog"` field to your Animal interface and have the Cat interface have `type: "cat"`. If works well and is very similar to a JVM Class object or .NET Type object.

Structural typing, literal types and dependant types are major blessings to have available sometimes, and I'd really like languages to adopt some of Typescripts power and simplicity in this. So far I've only seen Julia have some of it, although Scala 3 also introduces some bits.

Re:TypeScript’s quirks: How inconsistencies make the languag... by kazinator on Monday February 03, 2020 @06:22PM (#22230487)
What is a boon is that I can write code that accesses obj.breed and have it work with any object that has a breed property.

That has some downsides; it can be abused to create a ball of mud.

However, a middle-of-the-road type check which insists that an object must have all of the properties of Dog, even ones you're not using, isn't very useful. It kills the above dynamism, and yet allows abuses to sneak through.

You will not find that cats are being passed to Dog functions until you try to maintain Dog. And then you will discover that, oops, everything you add to Dog has to be replicated in Cat.

Basically, a typecheck which says that an object coming in has to have all the properties of Dog might as well just be a subclass check. The smart way to ensure that a non-Dog class has all the properties of Dog is inheritance.

A properly done static version of this structural type check would validate that the object being passed to the function doesn't have all the properties of a Dog, but that it has all the properties which just that function requires (including transitively: through any functions it calls).

Re:TypeScript’s quirks: How inconsistencies make the languag... by blobs on Saturday February 01, 2020 @05:36AM (#22209822)
Whatever words you use, it simply conflicts with basic JS and is a serious flaw.

  const cat = new Cat();
  if (cat instanceof Dog) console.log('this should never be possible!');

What is this strange protective behavior towards TS, can we stick to logic please?
Re:TypeScript’s quirks: How inconsistencies make the languag... by redmorphium on Saturday February 01, 2020 @06:25AM (#22209968)
instanceof checks the prototype chain, which is a different concept from type. Prototype chains are dynamic and exist at runtime, while Typescript types are a static concept.