Earlier quoted context omitted.
You can still do this with classes in typescript: class Hash extends String {} https://www.typescriptlang.org/play/?#code/MYGwhgzhAEASkAtoF...
That's distinguishing the String class from primitive string. I don't think that would still work with another `extends String` the same shape as Hash. For example: https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABO... class Animal { isJaguar: boolean = false; } class Automobile { isJaguar: boolean = false; } function engineSound(car: Automobile) { return car.isJaguar ? "vroom" : "put put"; } console.log(en…
Branded types for TypeScript
141–150 of 152 posts
Re: Branded types for TypeScript
#142I don't understand why users of branded types use strings as brands. Also using a utility type makes unreadable the TypeScript errors related to this type. If I had to use branded types, I personally would prefer a different approach: declare const USER_BRAND: unique symbol type User = { name: string, [USER_BRAND]: undefined } This also allows subtyping: declare const PERSON_BRAND: unique symbol type Person = { name:…
Re: Branded types for TypeScript
#143Re: Branded types for TypeScript
#144As someone who values a tight domain model (a la DDD) and primarily writes TypeScript, I've considered introducing branded types many times, and always decline. Instead, we just opt for "aliases," especially of primatives (`type NonEmptyString = string`), and live with the consequences. The main consequence is that we need an extra level of vigilance and discipline in PR reviews, or else implicit trust in one another…
> The other implementation is detailed in this article, and requires the addition of unique field value to objects. That's not quite what ends up happening in this article though. The actual objects themselves are left unchanged (no new fields added), but you're telling the compiler that the value is actually an intersection type with that unique field. There a load-bearing `as Hash` in the return statement of `gener…
Re: Branded types for TypeScript
#145It took me so long to fully appreciate TypeScript's design decision for doing structural typing vs. nominal typing. In all scenarios, including the "issue" highlighted in this article there is no reason for wanting nominal typing. In this case where the wrong order of parameters was the issue, you can solve it with [Template Literal Types]( https://www.typescriptlang.org/docs/handbook/2/template-lite... ). See [1]. A…
> In all scenarios [...] there is no reason for wanting nominal typing. Hard disagree. It's very useful to e.g. make a `PasswordResetToken` be different from a `CsrfToken`. Prepending a template literal changes the underlying value and you can no longer do stuff like `Buffer.from(token, 'base64')`. It's just a poor-man's version of branding with all the disadvantages and none of the advantages. You can still `hash.to…
Re: Branded types for TypeScript
#146Re: Branded types for TypeScript
#147Re: Branded types for TypeScript
#148Earlier quoted context omitted.
One tricky scenario I stumbled on is `.toString()`. Everything has a `.toString()` but some objects A have `.toString(arg1, arg2, arg3)`. But replacing A with something that does not have toString with arguments still type checks, yet will probably result in serious error.
This is sort of by design. Generally speaking Object.prototype.toString() does not accept parameters, I think the only "standard" implementation which takes parameters is Number.prototype.toString(). You can overwrite .toString with your customized functions, but doing so is full of risks which can basiclaly be summed up to performance overhead and unexpected behaviour due to how you're not really in control of an ob…
Re: Branded types for TypeScript
#149Earlier quoted context omitted.
No, neither Deno nor Bun does any type-checking. They both just convert the code to JS. To do type-checking you need to run TSC.
deno does type checking. https://docs.deno.com/runtime/manual/tools/check
Edit to add: I see, Deno embeds TSC as a library and tries to straighten out the mess of tsconfig. That must be a leaky abstraction, which makes me wary, but maybe it works well in practice.
Re: Branded types for TypeScript
#150Earlier quoted context omitted.
Without your example, I would've bet that TS uses structural typing for interfaces and nominal typing for classes.
I thought so too originally, was very surprised.
flowtype documentaiton: https://flow.org/en/docs/lang/nominal-structural/#toc-object...
Example: https://flow.org/try/#1N4Igxg9gdgZglgcxALlAIwIZoKYBsD6uEEAzt...