News for hackers. Stuff that matters.
Re:TypeScript: Branded Types by dvt on Thursday April 25, 2024 @03:23AM (#40154500)
> And once your own trusted code has made an OrgId, you don't need any runtime checking to see if it actually is an OrgId.

Right, and once I have a verified OrgId, I'll just keep using the `myOrgId` variable throughout my code, and I don't really need branding. Maybe I can do type aliasing to make the code easier to read (type OrgId = string), but hardline type verification via branding seems moot unless you can make strong runtime guarantees. I mean, don't get me wrong, I think it's a cute novelty, but it doesn't really do anything.

> But a new string will have a type like `string`, not `OrgId`, and then using it as an OrgId won't compile.

Exactly. Maybe I'm wrong, but in a real codebase, I bet branding would probably just confuse people. "Why can't I change the last number of an OrgId?"—well, you see, once you do that, you lose the brand so now you need to manually do `as OrgId`.

Re:TypeScript: Branded Types by kristiandupont on Thursday April 25, 2024 @04:38AM (#40154990)
If you have a function addMemberToOrg(memberId: string, orgId: string), you can accidentally call it like this: addMemberToOrg(myOrgId, myMemberId) and nobody will complain. With branded types, the compiler would mark it as an error.
Re:TypeScript: Branded Types by dvt on Thursday April 25, 2024 @02:49PM (#40161497)
Function signatures already solve that problem. We have all kinds of functions that take two numbers that mean different things (width/height, x/y, etc.). Branding seems like a solution looking for a problem. I just think it's too much overhead and confusion for too little gain.

In fact, a common pattern is to pass fully-qualified objects, e.g. `dimensions = {width: number, height: number}`, which makes mixing up variables even less likely since you have to explicitly specify them.

Re:TypeScript: Branded Types by kristiandupont on Friday April 26, 2024 @02:47AM (#40166560)
>Function signatures already solve that problem.

I literally just showed you how they don't. And you even go on to describe a pattern that makes the problem "even less likely" in the next sentence..

>Branding seems like a solution looking for a problem.

You do you.

Re:TypeScript: Branded Types by Dylan16807 on Thursday April 25, 2024 @04:48AM (#40155057)
> Right, and once I have a verified OrgId, I'll just keep using the `myOrgId` variable throughout my code, and I don't really need branding. Maybe I can do type aliasing to make the code easier to read (type OrgId = string), but hardline type verification via branding seems moot unless you can make strong runtime guarantees. I mean, don't get me wrong, I think it's a cute novelty, but it doesn't really do anything.

I would rather put that information in the type system than in the variable name.

It prevents passing the wrong variable, is that not useful?

> Exactly.

I don't see how what I said agrees with what you said. Making it not an OrgId prevents the weird blowups.

A compilation error because you used the wrong type is not a blowup, it's preventing random blowups.

And you shouldn't be shuffling digits using string code, that's the point. If you have a way to transmute OrgIds, it should be a function that returns an OrgId.

I'd question whether people even need to know OrgId is a string.

Re:TypeScript: Branded Types by dvt on Thursday April 25, 2024 @12:46PM (#40159835)
> I'd question whether people even need to know OrgId is a string.

I mean, with numbers it's even more confusing (this might be a TS bug?):

    type SpecialNumber = number & { __brand: "SpecialNumber" };
    let n: SpecialNumber = 42 as SpecialNumber;
    
    n++;        // works (but should break)
    n+=1;       // breaks
    n = n + 1;  // breaks
I understand the purpose behind it, I just think it's needlessly confusing and obtuse, and would be curious to see any serious code base that uses branding.
Re:TypeScript: Branded Types by sophiabits on Thursday April 25, 2024 @05:34AM (#40155327)
This sounds like an argument against TypeScript in general, no?

e.g. If I am parsing a string to a number via Number.parseInt, I don’t need a “: number” annotation because I can just call the variable “myNumber” and use that.

Branding a string is in many ways an extension on the idea of “branding” my “myNumber” variable as “: number” rather than leaving it as “: any”. Even if the TS type system is easy to bail out of, I still want the type annotations in the first place because they are useful regardless. I like reducing the number of things I need to think about and shoving responsibility off to my tools.