Live data from Hacker News

TypeScript: Branded Types

prosopo.io

51–60 of 209 posts

Re: TypeScript: Branded Types

#51

Earlier quoted context omitted.

FWIW, classes in TypeScript become nominal types when they have a non-public member. But I definitely do feel real FOMO over Flow’s opaque types.

Yes, ts is full of this kind kind of adhoc-ifs-like glued together, also exactness check only when it's literal object etc. Flow is more principled.

I mean. I think this specific case is a lot more principled than you seem to think. It’s certainly well reasoned from a perspective of structural typing by default.

Re: TypeScript: Branded Types

#52
post #45

Earlier quoted context omitted.

Nice. I don't love that example though, because the brand field's value of a string literal will make it seem like the object actually has a property named `__brand` when it doesn't. `never` is the best brand field type as far as I can tell.

`never` is a problematic field type, at least unless you make efforts (via non-exported symbols, for instance) to make sure the field is inaccessible - `never` is the type of a value that doesn't exist; it's there in the type system to signify an impossible scenario. For instance, a common use-case is to mark the type of a variable after type narrowing has exhausted every possible case. If you assert that your id's a…

Isn't that what you want to signify? It's the intent, and better than asserting that your IDs have a string-valued field that it doesn't.

Ideally you could brand with a private field, but we would probably need `typeof class` for that (assuming `typeof class` allows private members. I'm not sure).

Re: TypeScript: Branded Types

#53

Earlier quoted context omitted.

I think the example could be better in this article. Let's say you have a function that takes a database id, an email address, and a name. They're all strings. If you pass arguments to this function and you mess up the order for some reason then the compiler has no idea. Hopefully your unit tests catch this but it won't be as obvious. Branded types solve this problem because you can't pass a name string as an argumen…

That’s just plain encapsulation, if I understand you correctly. Branding, on the other hand, prevents complex types from being confused.

Branding works on primitive types as well, which is I think the most interesting use case.

I would also agree that it's harder to confuse complex types as any single instance of a type is unlikely to overlap once you have a few fields.

Re: TypeScript: Branded Types

#54
Weird idea, as types in TS are structural by design. If this is something you need, it smells like "runtime checking" not amending the type system.

Re: TypeScript: Branded Types

#55

Earlier quoted context omitted.

Rather, I think Typescript's philosophy of not having a runtime is simply wrong. Other statically typed languages retain type information at runtime. I don't understand why that was so important to explicitly exclude from Typescript.

If we needed a special Typescript runtime to use Typescript it would become nearly useless. The vast majority of Typescript becomes JavaScript running in Node or V8. The web is stuck with JavaScript, and Typescript is a tool to help us write maintainable JavaScript.

Could’t one write a TypeScript runtime in JavaScript or WASM?

Re: TypeScript: Branded Types

#56

I can see this being useful and it seems about as neat a solution as you can currently get in TypeScript as it stands today, but it’s still cumbersome. My feeling is that while you can do this, you’re swimming upstream as the language is working against you. Reaching for such a solution should probably be avoided as much as possible.

Rather, I think Typescript's philosophy of not having a runtime is simply wrong. Other statically typed languages retain type information at runtime. I don't understand why that was so important to explicitly exclude from Typescript.

Static typing information isn't retained at runtime. e.g.

    ListInterface list = new ConcreteList();
    let runtimeType = GetTypeOf(list); // will be `ConcreteList`, not `ListInterface`
This is an imaginary java-like language, but I'm not aware of a statically typed language that gives you the static type resolutions at run-time, outside of cases like implicit generic resolutions and things like that.

Re: TypeScript: Branded Types

#57

Flow is much better with opaque types. Also nominal types for classes. And correct variance. And adhering to liskov substitution principles. And exact object types. And spread on types matching runtime behavior. And proper no transpilation mode with full access to the language. And has 10x less LoC than ts. ps. before somebody says "flow is dead" have a look at flow contributions [0] vs typescript contributions [1] […

Check out the react codebase, which is presumably the flagship use of flow. It has hundreds of FLOW FIXME annotations. It's easier have a lot of features and small code base if the you don't handle the difficult cases.

Re: TypeScript: Branded Types

#58

I can see this being useful and it seems about as neat a solution as you can currently get in TypeScript as it stands today, but it’s still cumbersome. My feeling is that while you can do this, you’re swimming upstream as the language is working against you. Reaching for such a solution should probably be avoided as much as possible.

Rather, I think Typescript's philosophy of not having a runtime is simply wrong. Other statically typed languages retain type information at runtime. I don't understand why that was so important to explicitly exclude from Typescript.

So it’s Just JavaScript and the risk of adopting it is basically zero.

It’s the thing that made it an easy sell after everyone got turned off by the long-term experience of Coffeescript and such. It’s the reason various “better” typed languages that run on top of JS have flopped except with enthusiasts.

Re: TypeScript: Branded Types

#59

Flow is much better with opaque types. Also nominal types for classes. And correct variance. And adhering to liskov substitution principles. And exact object types. And spread on types matching runtime behavior. And proper no transpilation mode with full access to the language. And has 10x less LoC than ts. ps. before somebody says "flow is dead" have a look at flow contributions [0] vs typescript contributions [1] […

Tried Flow first, back in the day. I was ready to give up the whole idea as not-at-all-worth-the-trouble if Typescript had been as mediocre an experience.

Fortunately it wasn’t and now I get to not-hate working in JavaScript.

Re: TypeScript: Branded Types

#60

I can see this being useful and it seems about as neat a solution as you can currently get in TypeScript as it stands today, but it’s still cumbersome. My feeling is that while you can do this, you’re swimming upstream as the language is working against you. Reaching for such a solution should probably be avoided as much as possible.

Rather, I think Typescript's philosophy of not having a runtime is simply wrong. Other statically typed languages retain type information at runtime. I don't understand why that was so important to explicitly exclude from Typescript.

The decision between structural and nominal typing has nothing to do with whether you retain type information at runtime.

TS could have just as easily chosen nominal typing + a simple way to do typedefs and had everything else work like it does now. But structural typing gives you a lot of other useful features.

Post reply on HN