Live data from Hacker News

TypeScript and Set Theory

ivov.dev

1–10 of 29 posts

Re: TypeScript and Set Theory

#2
> Finally, be aware that for a conditional type to trigger distributivity, the checked generic must be by itself to the left of extends, that is, not passed into another generic or otherwise altered during the check.

Ah, this helped my brain click with a problem I’ve encountered several times. I think the most common reason I encounter this is when using generic memoized components in React. The generic parameters seem to be missed by the compiler completely, so something like a memoized polymorphic component becomes impossible to compose further into other components.

I guess the problem is that the memo function has inferred generic parameters which causes distributivity to be disabled on the nested generic parameters.

At least I think this is the case. I need to dig a little deeper, but I’m fairly sure this explains it.

This was a great read. I intuitively think in sets quite often, but it hadn’t occurred to me how overt the set theory is in TypeScript. This opened my eyes to the reason behind certain unintuitive behaviours (especially intersecting interfaces).

Re: TypeScript and Set Theory

#6

> Finally, be aware that for a conditional type to trigger distributivity, the checked generic must be by itself to the left of extends, that is, not passed into another generic or otherwise altered during the check. Ah, this helped my brain click with a problem I’ve encountered several times. I think the most common reason I encounter this is when using generic memoized components in React. The generic parameters se…

As an aside, a workaround for that case is:

  const Comp = React.memo(NonMemoComp) as typeof NonMemoComp

Re: TypeScript and Set Theory

#10
The section on how union & intersection types behave with interfaces (rather than primitives) has them flipped: a union of interfaces will allow access to only the intersection of the fields/methods of all the types (unless you do the work to distinguish between which type you're working with), while an intersection will allow access to the union of the fields/methods of the composed types.

i.e. `ICat | IDog` will only allow `pet.eat()`, and `ICat & IDog` will allow `pet.eat()`, `pet.meow()`, and `pet.bark()`.

Good article otherwise, though. The explanation of top/bottom types was more intuitive than most attempts.

Post reply on HN