There was no perfect solution available, so a tradeoff was necessary. You can disagree with this particular tradeoff, but had they gone another way some people would disagree with that as well. To be a mistake there would have had to have been an option available that was clearly better at the time.
Anyway, the idea that TS 5 should be backwards compatible with TS 1 is probably a bad one. Personally, I think packages with wide usage break backwards compatibility far too easily -- it puts everyone who uses it on an upgrade treadmill, so it should be done very judiciously. But even I wouldn't argue that TS 1 should have been its final form.
I think Rust made the really smart move of putting :: before any type parameters for functions. Go made the good move of using square brackets for type parameters.
We really need five sets: grouping, arrays/indexing, records, type parameters, and compound statements. Curly braces {} are also overloaded in JS for records and compound statements, leading to x => {} and x => ({}) meaning different things.
Square brackets wouldn't work for parametric functions because f[T](x) already means get the element at index T and call it.
That's an interesting topic. Do you happen to know if UTF-8 contains more "pair" characters? In Latex we call these delimiteres, but that's just my limited experience coming in from math side. I tend to agree that it would be helpful to have more kind of nesting/pairing/grouping/delimiting characters. The problem is my imagination is limited to what I know from the ASCII world, and so it goes... no idea what new sets would look like.
Which brings us to the philosophical question about paired characters: If we were to pick paired characters from a key set not available on everyone's keyboard, why must the paired characters even be used in real languages? Is that not actually actively detrimental when we end up needing the characters for real? Is this not why we even have escape characters to begin with?
Plus, must they be a part of anyone's real keyboard to begin with? What makes 「」any more valid than ¿? Could we not have saved ourselves a lot of mental strain if we solved it earlier on with a full set of truly uncommon characters?
I can imagine an alternate history, where some programming language in the late 70's made their editors with simple shortcuts (such as Ctrl+A for "array block") to input barely-if-ever-used yet low code character such as † or ‡, which would never be used outside of a string. And nowadays, with modern IDE's, we wouldn't even see those characters half the time. It would be syntax sugar, with blocks types stated in gutters and data types represented with colors or text.
https://www.reddit.com/r/rust/comments/5penft/comment/dcsq64...
UTF-8, UTF-16, UTF-32 all have the same characters.
In most languages, (grouping and compound statements) cannot syntactically appear in the same place as (indexing, records, type parameters, function calls). So we are immediately down to four.
Rust takes the approach that you use :: before type parameters, so they are easily distinguished from comparison operators at a syntactic level.
Go takes the approach that [] is just fine for type parameters—which seems pretty reasonable to me. In Go, there’s nothing that can be both indexed *and* take a type parameter.
True, but TypeScript has a rule against type-dependent emit - it’s not allowed. Code must always do the same thing regardless of what the types are. And in any case JavaScript does allow indexing on functions, since functions are just objects.
(And they could even converted to unicode by the code formatter)
You could argue that it was a C++ mistake. It makes parsing harder, but otherwise seems to work as expected, so I don't consider it a mistake, but you could at least argue that way.
But regardless if it was a mistake in C++, it's now a complete standard, used in C++, Java, C#, and other languages to denote type parameters.
I would argue that it would have been a mistake to break that standard. What would you have used, and in what way would that have been enough better to compensate for the increased difficulty in understanding TypeScript generics for users of almost every other popular language?