4 ms·
> Arrays are covariant in their type param, so I can pass a `Dog[]` into a function that accepts `Animal[]`. If that function adds a `Cat` to the passed array,
by skitter 5y ago
> Arrays are covariant in their type param, so I can pass a `Dog[]` into a function that accepts `Animal[]`. If that function adds a `Cat` to the passed array, the compiler is perfectly happy, but we'll see a runtime error.
The same is true for Java arrays. I thought the Liskov substitution principle was tautological when I first heard about it, but it seems like the original designers of Java disagree. Another example (albeit from the standart library, not the typesystem itself) is that if you try to modify a `List` or similar collection, it may throw an `UnsupportedOperationException` because it's immutable - instead of having a superinterface with only non-mutating methods and only implementing that.
- qsort 5y ago> The same is true for Java arrays. This is an unfortunate relic of pre-1.5 Java. The rest of the Collection API types correctly. A type-safe generic alternative is Arrays::setAll. > if you try to modify a `List` or similar collection, it may throw an `UnsupportedOperationException` Again, an historical artifact. `List` is from Java 1.2, you would effectively have to deprecate List<T> for that to work.
- bobthebuilders 5y agoMost of these things in TS are due to historical artifacts too. Namely code patterns that would not work well without them.
- ragnese 5y agoUgh. You're going to make me defend Java? I'm going to need a drink... First point: Yes, Java's arrays are broken and it offends me greatly. However, in practice, it's much more common to use Lists, which are not broken. In JavaScript/TypeScript "Array" is the equivalent of Java's List, so if you want a dynamically sized, contiguous, collection, you are stuck with the broken thing. Then, the other issue is that, despite my comment's wording, this problem isn't ONLY present in Arrays. It's also a problem with objects, and (I assume) every other non-primitive type. See here: https://www.typescriptlang.org/play?#code/MYGwhgzhAECCB2BLAtmE0DeBfAsAKFEhgGEwAXaAUwA8zL4ATGBFNTfaT6ZSgewHcAFAEoAXNABuvRA3Z4uC6MF7wIvEJQB0IXgHNBAIh4CDwjl1x5LhKNAAieqrXpM4SVOgznOAIzAAnAGsRcSkZOUUuZVV1LR19Az8g029oS0t8RHg6fwAzMGBKaAAJSAAFSgoveS4AB0rxFg98DLwsnPzCksgHXQi6hvs9Fvx8XIBXeGAyRBVuMCRa8fA6CrJBXnFSiDXhfs5eTXqKAF5oeEp+aFJ1sytRghUICk3uiF7oM+qFY-ELq96IhGeHwqEWy3IlDWGzu+EOx00SWCewA9CilLxkLVEBp-NBEDB6nlKNMQABPaAACzAtVqZIAhEA https://www.typescriptlang.org/play?#code/MYGwhgzhAECCB2BLAt... So even a basic object field is broken in TypeScript's type system. What the hell are we supposed to do with this? I do have thoughts and opinions about Java's Collection interfaces, the immutable implementations, etc, but that feels like a whole other topic.
- jakear 5y agoYes, TypeScript’s type system is unsound. Yes. Flow handles some of these cases better, but the invisible keyboard of the market has decided that the extra conceptual/syntactical overhead of introducing co/contravariant types is not worth it for these corner cases. You may disagree, that’s fine. But I’d suggest treating the problem as the engineering tradeoff that it is rather than an absolute fact that every type system must not have any holes and those that do are worthless.
- ragnese 5y agoThe invisible keyboard of the market... guided by millions of dollars from Microsoft, I assume. > rather than an absolute fact that every type system must not have any holes and those that do are worthless. Also, don't straw man me, please.
- jakear 5y ago> So even a basic object field is broken in TypeScript's type system. What the hell are we supposed to do with this? > So a hole exists in TypeScript's type system. What the hell are we supposed to do with this? > So a hole exists in TypeScript's type system. How can this be useful? > A hole exists in TypeScript's type system, therefore it is not useful. > Every type system must not have any holes and those that do are worthless. Where's the straw? Regardless, the issue you pose is solved via generics, which would be the appropriate TS way to model this: https://www.typescriptlang.org/play?#code/MYGwhgzhAECCB2BLAtmE0DeBfAsAKFEhgGEwAXaAUwA8zL4ATGBFNTfaT6ZSgewHcAFAEoAXNABuvRA3Z4uC6MF7wIvEJQB0IXgHNBAIh4CDwjl1x5LhKNAAieqrXpM4SVOgznOAIzAAnAGsRcSkZOUUuZVV1LR19Az8g029oS0t8RHg6fwAzMGBKaAAJSAAFSjIAHgqKAF43VhAAPgiuAAdK8Vr8DLwsnPzCksgHXTbOTrJxMd78fFyAV3hgMkQVbjAkdsXwOlqayoAVAE9O5sFecVKIA9rT8+EJ6F5NKegG+Ep+aFIyETmeHw0QgFCuIwgYw+zym4i+PzGAKs8zwqG2u3IlFqlzMQLwrymmiSwSeAHpSUpeMh2ogNP5oIgYJ08pRViATtAABZgdrtE4AQiAA https://www.typescriptlang.org/play?#code/MYGwhgzhAECCB2BLAt... Similar constructs would solve your proposed Array issues too: https://www.typescriptlang.org/play?#code/MYGwhgzhAECCB2BLAtmE0DeBfAsAKFEhgGEwAXaAUwA8zL4ATGBFNTfaT6ZSgewHcAFAEoAXNABuvRA3Z4uC6MF7wIvEJQB0IXgHNBAIh4CDwjl1x5LhKNAAieqrXpM4SVOgznOAIzAAnAGsRcSkZOUUuZVV1LR19Az8g029oS0t8RHg6fwAzMGBKaAAJSAAFSjIAHgqyABUATwAHIoBeN1YQAD4IrhaycVrGlvwMvCyc-MKSyAddXs5+8TnR-HxcgFd4YDJEFWgwBgZSarqnOkZmdzQuwQD-cTqAbQBdYQWD-39NJo2IAAtBPBKPxoCcRGYrEA https://www.typescriptlang.org/play?#code/MYGwhgzhAECCB2BLAt... TS is explicitly designed to be easy to apply to existing codebases without terribly much work. This means it must allow unsound code in some cases. However, given it also provides mechanisms to make the code sound, I do not see why this must be a dealbreaker to you. I think if you took the time to learn it you'd find the type system is actually quite powerful. (Disclaimer work at MSFT on their TS editor)