> That's a strange claim. I mean, yeah, maybe you can say that it's more advanced than "vanilla" Haskell, but how many people use no extensions at all?

Let me broaden that then. Typescript's type system is more expressive than even the proposed list of GHC2021 extensions. You really need to turn on "GHC and the kitchen sink" (basically your code is probably going to be using the singletons library and everything that entails) to get to the feature set of Typescript's type system. I think that's beyond what the vast majority of Haskellers use or are comfortable with.

> But when compared to Scala 3 - is there anything major that you can do with typescript but not with Scala 3?

Plenty. Part of it has to do with the fact that interfaces are truly structural types in Typescript whereas traits are still nominal in Scala 3. So for example, Typescript lets you have "complement types" (i.e. give me all the fields of A except those in B) which you cannot do in Scala 3.

Here's an example of a useful type-level thing I've found myself wanting all the time in Haskell and Scala that is very straightforward in Typescript.

Often we have a record

data MyRecord = MyRecord
{ field0 :: Int
, field1 :: Bool
, field2 :: Bool
}

that must undergo validation first before we can generate the record (e.g. parse out a bunch of strings for each field into Ints and Bools where those parse operations may fail).

It is tedious to write a whole new data type which duplicates all the fields, but just adds a Maybe in front of each type. Haskell has a design pattern known as "higher-kinded data types" that tries to mitigate that.

data MyRecord f =
{ field0 :: f Int
, field1 :: f Bool
, field2 :: f Bool
}

In its more sophisticated form we can use type families instead of normal higher-kinded types along with TypeApplications to make this fully seamless and get rid of a lot of Identity wrappers. Scala 3 allows something similar with match types (in fact you don't even need match types for getting rid of Identity wrappers due to Id in Scala being a type synonym and being able to do the equivalent of TypeApplications for higher-kinded type synonyms).

This approach, however, doesn't quite work if you have multiple validation steps that return multi-field fragments of MyRecord (e.g. one step returns a fully validated field0 and field1 and another returns a fully validated field2). You basically need to resort to writing a bunch of duplicated types again (type families can kind of save you if you happen to have all entirely distinctly types).

Typescript's mapped and conditional types handle this with aplomb, letting me generate any combination of fields wrapped in any combination of types from a single type definition.

Separately, in another comment in this same chain I give an example of (limited) dependent types in Typescript. I think you can replicate it with singletons in Haskell, but that's definitely getting into stuff that I would say "doesn't compose and does not age very well" in Haskell (ah should the blessed day that dependent Haskell lands arrive soon!). AFAIK you can't replicate that in Scala 3 because of a lack of value to type promotion mechanisms (I think even with match types it's not quite sufficient).