Live data from Hacker News

TypeScript: Branded Types

prosopo.io

61–70 of 209 posts

Re: TypeScript: Branded Types

#61

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] […

[deleted]

Re: TypeScript: Branded Types

#62
post #45

Earlier quoted context omitted.

`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).

From the direction of construction, it is - as a marker of "I want to never be able to construct this value - the only way I should be able to construct this value is in an impossible state", sure, it works.

But from the direction of usage...because you've used casting to (as far as TypeScript is concerned) construct the value, once it's floating around you're in an impossible state - and no, having a branded thing should not be an impossible state. Because of that you can freely violate the principles of the type system's logic - ex falso quodlibet.

A never value is effectively an any value, and now you have one on hand at all times.

https://www.typescriptlang.org/play?#code/FAMwrgdgxgLglgewgA...

Re: TypeScript: Branded Types

#63
post #26

Earlier quoted context omitted.

Ah, yeah the error makes sense. I expected the error, just wanted to understand how Brand was meant to be actually assigned to a primitive. I'm not sure the function is necessary though. This does the same thing const accountId = "125314" as AccountId It makes sense that the technique uses casting.

The function is great in cases where you can validate the string, or paired with lint rules that limit casting.

[deleted]

Re: TypeScript: Branded Types

#64

Earlier quoted context omitted.

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?

It wouldn't be very useful, since a TS-in-JS runtime would have significant performance overhead, and a TS-in-WASM runtime would have very expensive JS interop plus cross-language-GC hurdles. Might be less bad with WASM GC.

Re: TypeScript: Branded Types

#65

Earlier quoted context omitted.

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?

With horrible overhead, and in the case of WASM, lots of serialization and API glueing (DOM is just somewhere near the tip of the iceberg) woes, maybe?

Would be a fun thing to do for sure, but never as fast as the APIs built into the browser runtime.

Re: TypeScript: Branded Types

#66
This works because casts are allowed to quietly create values whose types are wrong. It would have been better if the cast added a runtime check, or at least we distinguish sound (checked) and unsound casts the way C++ does.

I think Haskell avoid this by actually requiring you to write sound conversion functions between phantom types (it helps that phantom types don't involve any visible state at runtime).

Re: TypeScript: Branded Types

#68
post #67

Ah, the magical disappearing type system - now being used for nominal typing. I'm curious to see what the JS code looks like for casts and type checks in that case.

Nothing special about casts and type checks. It’s just a simpleish workaround for when nominal typing is more useful

Re: TypeScript: Branded Types

#69

This works because casts are allowed to quietly create values whose types are wrong. It would have been better if the cast added a runtime check, or at least we distinguish sound (checked) and unsound casts the way C++ does. I think Haskell avoid this by actually requiring you to write sound conversion functions between phantom types (it helps that phantom types don't involve any visible state at runtime).

As a TypeScript beginner, I was bitten by this. Typing in TypeScript feels quite bad for some reason; a lot of effort for effects which are still potentially wrong at runtime. I didn’t struggle so much in Python, Rust or C#, for example. Python is surprisingly… sound? in comparison. It can do nominal as well as structural typing.

Re: TypeScript: Branded Types

#70
post #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.

Design doesn’t cover all use cases. There’s nothing weird about wanting different types for “user id” and “organisation id” so that you don’t use the wrong argument by mistake
Post reply on HN