Live data from Hacker News

TypeScript and Set Theory

ivov.dev

11–20 of 29 posts

Re: TypeScript and Set Theory

#12

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

That's incredibly interesting, because I've been using union types a while and didn't know this. I think a lot of people will get introduced to them via function signatures, and var: ICat | IDog not meaning "var could be an ICat or an IDog" is a bit unintuitive given the boolean math.

But ultimately more useful? As in, code should never test whether this thing is an ICat or IDog, and I guess it's interesting that I don't remember ever encountering an issue where I attempted to access a member that was only present on one interface.

Perhaps it would be too overloaded, but "ICat + IDog" instead of "ICat & IDog" feels more obvious, I suppose a better convention for "ICat | IDog" is difficult though. "ICat /\ IDog" for intersection and "ICat \/ IDog" for union doesn't roll off the tongue.

Re: TypeScript and Set Theory

#13
TypeScript also lets you create subsets of infinite size. For example, a string template literal type can be a type with (theoretically) infinite string values matching a string template.

I've created a proposal for doing something similar with the number type that uses the relational operators (, >=, It may be not as useful as template literal types (which is why one could argue to not implement them), but it's interesting nonetheless.

[1]: https://github.com/microsoft/TypeScript/issues/43505

Re: TypeScript and Set Theory

#14

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

That's incredibly interesting, because I've been using union types a while and didn't know this. I think a lot of people will get introduced to them via function signatures, and var: ICat | IDog not meaning "var could be an ICat or an IDog" is a bit unintuitive given the boolean math. But ultimately more useful? As in, code should never test whether this thing is an ICat or IDog, and I guess it's interesting that I d…

I think ICat | IDog is perfect. It means exactly that, the value can be of type ICat _OR_ IDog, so in that sense, we can only access properties that are in both of them until we know for sure if we are dealing with a ICat or a IDog specifically.

Re: TypeScript and Set Theory

#15
post #11

I just wanted to comment on the website, I really love this UI

That is very simple and beautiful website. Author did a great job both aesthetically and technically. I wonder if its a Framework like hugo or is it custom built?

Looking at the DOM, it's Next.js with Tailwind.

Re: TypeScript and Set Theory

#16
post #14

Earlier quoted context omitted.

That's incredibly interesting, because I've been using union types a while and didn't know this. I think a lot of people will get introduced to them via function signatures, and var: ICat | IDog not meaning "var could be an ICat or an IDog" is a bit unintuitive given the boolean math. But ultimately more useful? As in, code should never test whether this thing is an ICat or IDog, and I guess it's interesting that I d…

I think ICat | IDog is perfect. It means exactly that, the value can be of type ICat _OR_ IDog, so in that sense, we can only access properties that are in both of them until we know for sure if we are dealing with a ICat or a IDog specifically.

[deleted]

Re: TypeScript and Set Theory

#18
Conditional type expression are indeed very powerful and, little known fact, can be used to generate types recursively.

Here's a type signature from hell with its usage:

  type Component = { type: 'a' } | { type: 'b' };

  type FoundComponents = T extends [a: infer A] ? [Extract] :
  T extends [a: infer A, ...b: infer B ] ? [Extract, ...FoundComponents] : never;

  export function findComponentSets(components: Component[], ...componentTypes: T ): FoundComponents[];
  export function findComponentSets(components: Component[], ...componentTypes: Component['type'][] ): Component[][] { return [] }
It recursively picks outputs types based on the input parameters, so if you call e.g. findComponentSets([], 'a', 'b') the output type will be [{type: 'a'}, {type: 'b'}][].

I'm using it in an Entity Component System based game I'm writing to type check the function which receives a flat list of Components and type selectors and outputs a list of tuples with the selected Component types.

  findComponentSets(components, 'position', 'hit-box')
    .forEach(([position, hitBox]) => system.process(position, hitBox));

Re: TypeScript and Set Theory

#19
The naming of TypeScript Union and Intersection types, with respects to type theory, used to be terribly confusing/contradictory:

https://www.typescriptlang.org/docs/handbook/unions-and-inte...

See last paragram under «Unions with common fields»

Leading to terribly confusing TypeScript cheat sheets such as this (see the union and intersection venn-diagrams):

https://carltheperson.com/images/magic-typescript/magic-type...

Compare with: https://en.wikipedia.org/wiki/Intersection_(set_theory)

Luckily TypeScript recently updated their docs, and the issue has been clarified in posts such as this:

https://stackoverflow.com/questions/38855908/naming-of-types...

Turns out, naming things is really hard, because what you implicitly refer to when you unionize or intersect turns out to be of vital importance.

Post reply on HN