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[],…
TypeScript and Set Theory
21–29 of 29 posts
Re: TypeScript and Set Theory
#22The 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…
Sum = { tag: "left", data: X } | { tag: "right", data: Y }
Generally higher order types are named according to what they do to types, not terms. `x: ICat & IDog` means "x is in the intersection of ICat and IDog", not "x is the intersection of an ICat and an IDog". (The latter interpretation only even makes sense for record types and a few other special cases: what's the intersection of an integer and a string supposed to be?)Re: TypeScript and Set Theory
#23I just wanted to comment on the website, I really love this UI
Re: TypeScript and Set Theory
#24The 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…
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Re: TypeScript and Set Theory
#25Re: TypeScript and Set Theory
#26Conditional 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[],…
Re: TypeScript and Set Theory
#27Re: TypeScript and Set Theory
#28The 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-typ…
Re: TypeScript and Set Theory
#29> 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