Repository navigation
Design Meeting Notes, 10/6/2021 #46247
Copy link
Copy link
Closed
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Description
Andrew Branch (@andrewbranch) took notes for the first two items of this meeting
Check for Array Constraints When Instantiating Mapped Types with any
- Noticed an issue with
Promise.all:Promise.allonanyproducesPromise<Record<string, any>>#46169async function foo(x: any) { let abc = await Promise.all(x); let oops: any[] = abc; // Error: Type '{ [x: string]: any; }' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more.(2 }
- When you plug an
anyinto a mapped type, you get a Record fromstringtoany - Due to changes to
Promise.allin 4.5 - Proposal: if the thing we’re putting into
There is array-like, the output should be array-like too.declare function f<T extends unknown[]>(x: T): { [K in keyof T]: T[K] } f([1, 2, 3]) f(null as any)
- Check for array types when instantiating mapped type constraints with
any#46218 - Basically a one-liner
- Doesn't break any tests anywhere
- Check for array types when instantiating mapped type constraints with
- What's the equivalent of an any that's known to be an array? Or a tuple with a known arity?
- With
Almost feels like you should map over the constraint and return that?
declare function f<T extends [unknown, unknown]>(x: T): { [K in keyof T]: T[K] } let x = f([1, 2,]) let y = f(null as any)
- If an
anyflows in, should you really say the output has the right arity?
- If an
- Next issue:
type Arrayish<T extends unknown[]> = { [K in keyof T]: T[K] }; type Objectish<T extends unknown> = { [K in keyof T]: T[K] }; // Should always produce array types, but can't get this to work type IndirectArrayish<U extends unknown[]> = Objectish<U>; declare let x: IndirectArrayish<any>;
- Actually this would be really weird - the constraint type should maybe be considered local knowledge; a local artifact of
ArrayishorObjectish. Is it a dynamic attribute of the instantiation? It would need to be carried in the type, and that's not how type instantiation works.- When we check
Objectish<U>, we make sure thatUextendsunknown. Then, we instantiate withU, but there's no knowledge - well, I guess there could be - let's take it offline
- When we check
- Talking about generalizing this from arrays to tuples: it seems like you could generalize this to any base constraint.
type Objectish<T extends { x: string}> = { [K in keyof T]: T[K] }; declare let x: Objectish<any>; // could be { x: string } instead of { [key: string]: any }?
- Actually this would be really weird - the constraint type should maybe be considered local knowledge; a local artifact of
strictJsxAttributeChecks
- Resistance to having a flag for this. Is it enough bang for the buck?
- The loose checking of dashed properties is old kludge designed for
data-*. You can declare that now. We could add that signature to React typings and remove the hardcoded support from the compiler instead of flagging it at all. - Whatever we do, the user could add support back on their own with the global JSX namespace.
- Are we willing to take an external PR so we can experiment and see what breaks?
- Still don't want a flag.
- Maybe open to doing it unflagged if we see a lot of good come from it.
- PRs welcomed, not committed.
Conditions of Destructured Variables
type Action =
| { type: 'A', payload: number }
| { type: 'B': payload: string };
function reducer(state: Whatever, { type, payload }: Action) {
switch (type) {
case 'A':
payload.toFixed();
break;
case 'B':
payload.toUpperCase();
break;
}
}-
Want to be able to narrow
payloadbased on narrowingtype. -
PR has this working.
-
When destructuring a parameter, we know that there are no aliasing situations. That helps with the implementation.
- If you start out with an
actionand then destructure, that can be tricky.
- If you start out with an
-
We can narrow the group depending on whether it comes from a
constor parameter, and the declared type of the binding pattern as a whole is a union, then we see if we can narrow the types based on other destructured properties.- We create a pseudo-object type which
kindcan discriminate on. - Binding element is now a pseudo reference.
- We create a pseudo-object type which
-
Does modification reset narrowing?
- Yes, only
consts and unmodified parameters.
- Yes, only
-
Relies on these properties coming from the same destructuring pattern.
-
So this doesn't work?
const { kind } = action; const { payload } = action; if (kind === "A") { // payload ideally should be narrowed here. }
- No - no ways we can do that.
- However, we are able to narrow
actionbykind, which is nice. - Feels like a weird limitation.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Activity
treybrisbane commentedon Oct 7, 2021
Daniel Rosenwasser (@DanielRosenwasser) Just on mapped type behaviour with arrays/tuples: Have you guys at all considered having dedicated mapped type syntax for arrays/tuples? E.g. Something like
[ [I in indexof SomeTuple]: SomeTuple[I] ]?Not intended to be a feature request or anything. I'm mostly just curious if the idea of dedicated syntax has come up, as the interaction between the existing mapped types and arrays/tuples has always been a little quirky in my experience. 😄
DanielRosenwasser commentedon Oct 11, 2021
We did a while back - it was something that was discussed way back, and I was a proponent of it, but the idea that a mapped type on an array was so useless, in addition to the idea that you'd always have to add a conditional type to do the "right" thing, was something a lot of people on the team weren't big on.
[-]Design MeetingNotes, 10/6/2021[/-][+]Design Meeting Notes, 10/6/2021[/+]