Live data from Hacker News

TypeScript’s quirks: How inconsistencies make the language more complex

blog.asana.com

51–60 of 216 posts

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#51
post #24

Ok since we have a lot of TS people here maybe someone can help me out. Let's say I have a simple interface with a few fields. I want to make sure incoming JSON conforms to that interface. I realize at runtime the interface isn't there, but is there some tool I can use to compile a utility to check JSON against an interface without having to write a duplicative JSONSchema or something else?

I’d suggest generating code

Write your interface in json or text proto then build it to ts interfaces and runtime checks.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#52
post #24

Ok since we have a lot of TS people here maybe someone can help me out. Let's say I have a simple interface with a few fields. I want to make sure incoming JSON conforms to that interface. I realize at runtime the interface isn't there, but is there some tool I can use to compile a utility to check JSON against an interface without having to write a duplicative JSONSchema or something else?

My advice is bite the bullet and just write a JSON Schema for the interface and use ajv[1] to check it. Keep the interface, the JSON Schema, and the validator function (which should be a type guard[2] to take full advantage of TypeScript) in the same module for easier maintenance.

[1] https://github.com/epoberezkin/ajv

[2] https://www.typescriptlang.org/docs/handbook/advanced-types....

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#53
post #35

Earlier quoted context omitted.

Author here! Yeah I think you are right that discriminated unions are useful more broadly than just legacy JS code. That being said, I still think TypeScript's solution to handling them of using "type guards" where the type of a variable changes in different scopes is definitely designed to match common JS patterns at the cost of added complexity. Most other languages I know of only have a single type for a variable…

> Most other languages I know of only have a single type for a variable This may be pedantic, but with subtyping many OO languages can give many different distinct types for a variable. In Java you can assign any non-primitive typed expression to a variable of type Object. So almost any expression in Java can be typed as Object. What you are describing as novel is rather the phenomenon of type refinement in a pattern…

> In Java you can assign any non-primitive typed expression to a variable of type Object.

Sure, but if you do this in Java you must use different variable names for the reference of type Animal and the reference of type Object.

I think algebraic data types and type refinement are great, but I’m not a fan of automagically changing the types of variables in different scopes if it can’t be applied consistently.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#54
post #3

The first example doesn't bother me and I think it's a weak argument. TypeScript allows literals[1] as types[0] so it is trying to use the object as a type. The correct use of: printDog({ breed: "Airedale", age: 3 }) is to explicitly cast it: printDog({ breed: "Airedale", age: 3 } as Dog) [0] https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&p... [1] https://www.typescriptlang.org/docs/handbook/advanced-type…

The correct use is to remove the `age` property in this case: if you're not keeping a reference to the object or that property and the called function cannot use it, why have it in the first place?

That’s not always true. If you are going to print the object to the console or send it in a network request it’s possible that the additional property is important.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#55
post #20

I still don't understand what pulls developers to Typescript. The examples given show major flaws in this (duck)type system. That it works when you don't use the 'any' type and when you know how to avoid all the edge cases and workarounds, I know. But when I see an example like this: const shasta = new Cat("Maine Coon") printDog(shasta) > Dog:Maine Coon I see a huge red flag. Coming from C/C++ it looks like a joke. W…

It just means that structural types are the default and you need to opt in to nominal types, when necessary: https://www.typescriptlang.org/play/?ssl=13&ssc=1&pln=13&pc=... (there are other ways as well) In something like Java, it's the opposite: you get nominal types by default and you need to opt in to structural types (via interfaces). Because TS is built on a duck typed language, tons of existing libraries would…

I think that Flow’s approach of using nominal types for classes and structural for everything else makes more sense. Are there really cases you expect classes to be structural types?

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#56
post #22
post #20

I still don't understand what pulls developers to Typescript. The examples given show major flaws in this (duck)type system. That it works when you don't use the 'any' type and when you know how to avoid all the edge cases and workarounds, I know. But when I see an example like this: const shasta = new Cat("Maine Coon") printDog(shasta) > Dog:Maine Coon I see a huge red flag. Coming from C/C++ it looks like a joke. W…

Because you can get some decent typing with some compiler help AND leverage the entire node/js eco system super easily. Which is kind of the whole point. As someone that's done c/c++/c#/lua/js/ts I've found typescript to be really awesome because it differentiates the types from the objects. Which has given me a much better appreciation of typing rather than the traditional OOP everything.

What do you mean by “differentiates the types from the objects”? Could you maybe offer an example comparing TS and C#?

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#57
post #39

Typescript is great but it has its evils because it’s a superset of JavaScript. I really hope we get a modern language like c# where the types are guaranteed compile + runtime and you can’t any-ignore problems. The more I use typescript I realize I want a more sound and stricter language. Like no prototype overriding at runtime.

Noooo! Go away with those ideas! JavaScript is great because it’s not strict. That’s the flexibility that allows for speed. I have like 30 different APIs I implement at work, but I only pull out a few attributes from each. I don’t want to go to the moon and back creating types for all this crap, I’ll have more than a 100 different types to model because of all the nested data and convoluted structures the APIs return…

Counterpoint: https://lexi-lambda.github.io/blog/2020/01/19/no-dynamic-typ...

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#58
post #25
post #24

Ok since we have a lot of TS people here maybe someone can help me out. Let's say I have a simple interface with a few fields. I want to make sure incoming JSON conforms to that interface. I realize at runtime the interface isn't there, but is there some tool I can use to compile a utility to check JSON against an interface without having to write a duplicative JSONSchema or something else?

io-ts [1] is what I think most people use for this 1: https://github.com/gcanti/io-ts

Personally I dislike the fact that io-ts requires taking a pure functional programming approach to this validation. For most cases I just want to throw an error if something doesn't match up. My main use case for this is validating that my UI and backend API have the same ideas about the shape of the data, which will either always work or always fail. All errors should be caught during development and testing, so the "either" case will never realistically be hit in production.

Because of this I prefer runtypes [1], because it's much more simple to get my desired behavior. My only gripe is that errors aren't all that descriptive.

I guess I could write a function to pipe/fold into the type, throwing a descriptive error if something fails, but I like the simplicity of runtypes.

Edit: I just discovered io-ts ErrorReporter [2]. That's way better than my solution, and I'm considering switching now!

1: https://github.com/pelotom/runtypes

2: https://github.com/gcanti/io-ts/blob/master/src/ThrowReporte...

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#59
post #20

I still don't understand what pulls developers to Typescript. The examples given show major flaws in this (duck)type system. That it works when you don't use the 'any' type and when you know how to avoid all the edge cases and workarounds, I know. But when I see an example like this: const shasta = new Cat("Maine Coon") printDog(shasta) > Dog:Maine Coon I see a huge red flag. Coming from C/C++ it looks like a joke. W…

> I still don't understand what pulls developers to Typescript... Coming from C/C++ it looks like a joke.

Remember that this all compiles down to JavaScript where it's all dynamic/weak types. Someone coming from C/C++ should definitely appreciate TypeScript over just plain JavaScript.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#60

Earlier quoted context omitted.

The correct use is to remove the `age` property in this case: if you're not keeping a reference to the object or that property and the called function cannot use it, why have it in the first place?

That’s not always true. If you are going to print the object to the console or send it in a network request it’s possible that the additional property is important.

But then it should be in the type signature of the object. TypeScript is signalling this as an error because it's a literal passed directly to the function and that property (theoretically) can never be used because it wasn't declared.
Post reply on HN