GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Improved mapped type support for arrays and tuples by ahejlsberg · Pull Request #26063 · microsoft/TypeScript Conversation
Member
This PR improves our support for arrays and tuples in homomorphic mapped types (i.e. structure preserving mapped types of the form type Box<T> = { value: T }; type Boxified<T> = { [P in keyof T]: Box<T[P]> }; type T1 = Boxified<string[]>; // Box<string>[] type T2 = Boxified<ReadonlyArray<string>>; // ReadonlyArray<Box<string>> type T3 = Boxified<[number, string?]>; // [Box<number>, Box<string>?] type T4 = Boxified<[number, ...string[]]>; // [Box<number>, ...Box<string>[]] type T5 = Boxified<string[] | undefined>; // Box<string>[] | undefined type T6 = Boxified<(string | undefined)[]>; // Box<string | undefined>[] Previously, we would treat array and tuple types like regular object types and transform all properties (including methods) of the arrays and tuples. This behavior is rarely if ever desired. Given a homomorphic mapped type
Homomorphic mapped types can use type T10 = Partial<[number, string]>; // [number?, string?] type T11 = Required<[number?, string?]>; // [number, string] In type T20 = Partial<string[]>; // (string | undefined)[] type T21 = Required<(string | undefined)[]>; // string[] A Homomorphic mapped type support for tuples makes it possible to transform variable length parameter lists, eliminating the need for repetitive patterns overloads in several scenarios. For example: type Awaited<T> = T extends PromiseLike<infer U> ? U : T; type Awaitified<T> = { [P in keyof T]: Awaited<T[P]> }; declare function all<T extends any[]>(...values: T): Promise<Awaitified<T>>; function f1(a: number, b: Promise<number>, c: string[], d: Promise<string[]>) { let x1 = all(a); // Promise<[number]> let x2 = all(a, b); // Promise<[number, number]> let x3 = all(a, b, c); // Promise<[number, number, string[]]> let x4 = all(a, b, c, d); // Promise<[number, number, string[], string[]]> } This PR implements much of what is suggested in #25947, but without introducing new syntax.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Nathan Shively-Sanders (sandersn)
approved these changes
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One small question/comment.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo:homomorphic
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth extracting this calculation into a function.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isOptional doesn’t have any meaning for arrays, does it? Why not pass false if that’s true?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Mohamed Hegazy (mhegazy)
approved these changes
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
4 tasks done
4 tasks done
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
This was referenced
Closed
Collaborator
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Closed
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
Jack Bates (jablko)
added a commit
to jablko/TypeScript
that referenced
this pull request
|
There was an error while loading. Please reload this page.
|
For anyone who is struggling with prototype properties getting mapped as well (like in Roaders's #26063 (comment)), causing type Boxified<T> = { [P in keyof T]: P extends keyof [] ? T[P] : Box<T[P]> }; instead of type Boxified<T> = { [P in keyof T]: Box<T[P]> }; (It worked implicitly in |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Anders Hejlsberg (@ahejlsberg) it appears this only works on type aliases, rather than any homomorphic mapped type? It's always been surprising to me when the left and right hand sides of a type alias aren't interchangeable. At this point I wish an operator like |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
The higher-order behavior only applies to generics, so bare object type expressions are never homomorphic; only aliases are. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sometimes I wish I could do a one-off tuple mapping inline instead of having to declare a type alias out of line. And very often, I wish I could distribute over a union type inline instead of using a distributive conditional type alias |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
See #27995 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.