Live data from Hacker News

Branded types for TypeScript

carlos-menezes.com

121–130 of 152 posts

Re: Branded types for TypeScript

#121
post #3

In most languages, doing what this article describes is quite straightforward: you would just define a new type (/ struct / class) called ‘Hash’, which functions can take or return. The language automatically treats this as a completely new type. This is called ‘nominal typing’: type equality is based on the name of the type. The complication with TypeScript is that it doesn’t have nominal typing. Instead, it has ‘st…

What you say is true, but after years of working with TypeScript (and about 15 years of Java before that) I'd say that from a purely practical perspective the structural typing approach is much more productive. I still have PTSD from the number of times I had to do big, painful refactorings in Java simply because of the way strong typing with nominal types works. I still shudder to think of Jersey 1.x to 2.x migratio…

Overall I do like working with Typescript and structural typing does have some real advantages but, like just about everything in engineering, there are also tradeoffs.

Without some discipline you can create some very messy type spaghetti with TS. Nominal typing is more rigid but it can also force you to think more clearly about and carefully define the different entities in your system.

Re: Branded types for TypeScript

#122

Earlier quoted context omitted.

> In most languages, doing what this article describes is quite straightforward Well, no. In most languages you wind up making a typed wrapper object/class that holds the primitive. This works fine, you can just do that in TypeScript too. The point of branded types is that you're not introducing a wrapper class and there is no trace of this brand at runtime.

There's never any trace of typescript types at runtime.

Well, enums.

Re: Branded types for TypeScript

#124
post #3

In most languages, doing what this article describes is quite straightforward: you would just define a new type (/ struct / class) called ‘Hash’, which functions can take or return. The language automatically treats this as a completely new type. This is called ‘nominal typing’: type equality is based on the name of the type. The complication with TypeScript is that it doesn’t have nominal typing. Instead, it has ‘st…

Btw, there are quite a few language that have nominal typing, but use the equivalent of structural typing in their unions.

Eg in Rust or Haskell you can distinguish `Option>`, but not in these languages. I guess Python and Typescript are examples of these?

Re: Branded types for TypeScript

#125
post #21

It 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…

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.

Re: Branded types for TypeScript

#128

Earlier quoted context omitted.

What you say is true, but after years of working with TypeScript (and about 15 years of Java before that) I'd say that from a purely practical perspective the structural typing approach is much more productive. I still have PTSD from the number of times I had to do big, painful refactorings in Java simply because of the way strong typing with nominal types works. I still shudder to think of Jersey 1.x to 2.x migratio…

I think proper type inference along with some sort of struct literal syntax could make a lot of these problems go away without the need for structural typing. If you can create structs without explicitly mentioning the type (as long as it can be inferred), then you can use the same syntax for different types as long as their signatures are the same. Structural typing makes it too easy to accidentally pass something t…

All valid javascript programs are valid typescript programs, so typescript necessarily must have structural type, it cannot have nominal type without breaking compatibility with javascript, which is a hard requirement.

Re: Branded types for TypeScript

#129
Has something changed in TypeScript? There have been a few of these blog posts about branded types lately, but afaik, it's been possible to do this for years.

One of the projects I work on is crying out for better support for nominal typing. It involves manipulating music notation, and there are so many things passed around that are all strings, but semantically different: a note ("A"), a pitched note ("A4"), a key ("A minor"), etc etc etc. Life would definitely be easier if I could just quickly and conveniently declare the types to be distinct.

I do use the branded types thing, but it's a bit clunky and sometimes gets in the way. And the error messages you get aren't as clear as you would like.

Re: Branded types for TypeScript

#130

Earlier quoted context omitted.

I think proper type inference along with some sort of struct literal syntax could make a lot of these problems go away without the need for structural typing. If you can create structs without explicitly mentioning the type (as long as it can be inferred), then you can use the same syntax for different types as long as their signatures are the same. Structural typing makes it too easy to accidentally pass something t…

All valid javascript programs are valid typescript programs, so typescript necessarily must have structural type, it cannot have nominal type without breaking compatibility with javascript, which is a hard requirement.

Correct. My comment was about programming languages in general and not specific to TypeScript. :)
Post reply on HN