Earlier quoted context omitted.
I can't really argue with that. It's a way to get nominal types in a language that has structural typing. Even though the usage is simple, the implementation is more complicated than it should be. If for example the language was missing builtin hashmap type, its implementation would be nasty as well. I'm not a huge fan of typing systems, the thing I like the most in TypeScript is that you can use types as little as y…
> languages like go that intentionally lack features people will go as far down the rabbit hole as you let them, which is what the Go developers understand and are trying to account for: https://www.hyrumslaw.com
TypeScript: Branded Types
201–209 of 209 posts
Re: TypeScript: Branded Types
#202Flow 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] […
Flow regularly crashed with bizarre segfaults errors, the last time I used it.
Re: TypeScript: Branded Types
#203Earlier quoted context omitted.
it doesn't. never prevents reading and readonly prevents (over)writing. GP just focused on the never -part of your question.
never means nothing can be assigned to it, so in that sense it's already readonly
I wouldn’t call myself an expert in TypeScript’s type system (although I use it daily), so I’m not sure about that one.
I do know I would have omitted readonly if I did this myself, but perhaps by mistake.
Re: TypeScript: Branded Types
#204Earlier quoted context omitted.
It’s very readable to me, and is much cleaner than the notation in the article. Is your problem the line wraps in the parent’s comment?
this is readable? export type Brand = T & { readonly [B in Brand as `__${B}_brand`]: never; }; I count 14 different pieces of punctuation. you might as well use Perl at that point.
from typing import NewTypeRe: TypeScript: Branded Types
#205Earlier quoted context omitted.
function foo(customerId, itemId, orderId) { if(!customer[customerId]) throw new Error("Customer with id=" + customerId + " does not exist"); if(!item[itemId]) throw new Error("Item with id=" + itemId + " does not exist"); if(!order[orderId]) throw new Error("Order with id=" + orderId+ " does not exist"); } Just an example of how you can detect errors early with defensive programming.
As oppose to a zero cost build time check, that's 3 expensive runtime DB checks, plus an account and a member could have the same ID, so it might run anyways but on the wrong DB rows.
Re: TypeScript: Branded Types
#206Earlier quoted context omitted.
function foo(customerId, itemId, orderId) { if(!customer[customerId]) throw new Error("Customer with id=" + customerId + " does not exist"); if(!item[itemId]) throw new Error("Item with id=" + itemId + " does not exist"); if(!order[orderId]) throw new Error("Order with id=" + orderId+ " does not exist"); } Just an example of how you can detect errors early with defensive programming.
Yeah this is exactly why using primitive types for ids is bad. If you encode it in the type system then you cannot make this error and don't need to check it at runtime.
Re: TypeScript: Branded Types
#207Earlier quoted context omitted.
As oppose to a zero cost build time check, that's 3 expensive runtime DB checks, plus an account and a member could have the same ID, so it might run anyways but on the wrong DB rows.
You made two points that are correct in theory, but in practice those lookups would/could take micro-seconds, and the bug would be detected within minutes in a production environment. And it would take five minutes or less to patch.
Re: TypeScript: Branded Types
#208Earlier quoted context omitted.
You made two points that are correct in theory, but in practice those lookups would/could take micro-seconds, and the bug would be detected within minutes in a production environment. And it would take five minutes or less to patch.
If you're cowboy coding as a solo dev, sure.
Re: TypeScript: Branded Types
#209Earlier quoted context omitted.
How do ids of different types accidentally get into a place they shouldn't be? Is this simply a case where someone mistakenly passes along a property that happens to be called "id", not noticing it's an account id rather than a member id (as in, an implementation error)?
Happens a lot with junction tables ime. e.g. At my last job we had three tables: user, stream, user_stream. user_stream is an N:N junction between a user and a stream A user is free to leave and rejoin a stream, and we want to retain old data. So each user_stream has columns id, user_id, stream_id (+ others) Issues occur when people write code like the following: streamsService.search({ withIds: userStreams.map((stre…