GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Improved mapped type support for arrays and tuples by ahejlsberg · Pull Request #26063 · microsoft/TypeScript

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Jul 30, 2018

Copy link
Copy Markdown
Member

This PR improves our support for arrays and tuples in homomorphic mapped types (i.e. structure preserving mapped types of the form { [P in keyof T]: X }). When a homomorphic mapped type is applied to an array or tuple type, we now produce a corresponding array or tuple type where the element type(s) have been transformed.

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 { [P in keyof T]: X }, where T is some type variable, the mapping operation depends on T as follows (the first two rules are existing behavior and the remaining are introduced by this PR):

  • If T is a primitive type no mapping is performed and the result is simply T.
  • If T is a union type we distribute the mapped type over the union.
  • If T is an array type S[] we map to an array type R[], where R is an instantiation of X with S substituted for T[P].
  • If T is an array type ReadonlyArray<S> we map to an array type ReadonlyArray<R>, where R is an instantiation of X with S substituted for T[P].
  • If T is a tuple [S0, S1, ..., Sn] we map to a tuple type [R0, R1, ..., Rn], where each Rx is an instantiation of X with the corresponding Sx substituted for T[P].

Homomorphic mapped types can use ?, -?, or +? annotations to modify the optional-ness of tuple element types. For example, the predefined Partial<T> and Required<T> types have the expected effects on tuple element types:

type T10 = Partial<[number, string]>;  // [number?, string?]
type T11 = Required<[number?, string?]>;  // [number, string]

In --strictNullChecks mode the ?, -?, or +? annotations also add or remove undefined from the element type(s) of arrays and tuples:

type T20 = Partial<string[]>;  // (string | undefined)[]
type T21 = Required<(string | undefined)[]>;  // string[]

A readonly, -readonly, or +readonly annotation in a homomorphic mapped type currently has no effect on array or tuple elements (we might consider mapping from Array to ReadonlyArray and vice versa, although that technically isn't structure preserving because it adds or removes methods).

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.

jscheiny, j-oliveras, sean-vieira, vaskevich, alexrock, yortus, jcalz, KaelWD, HerringtonDarkholme, c69, and 37 more reacted with thumbs up emoji j-oliveras, sean-vieira, vaskevich, jcalz, haltcase, hax, c69, dsherret, bfricka, AlexeyMz, and 8 more reacted with hooray emoji jcalz, Hotell, alitaheri, JoshuaKGoldberg, Offirmo, h-a-n-a, klesun, thibaultboursier, kaguya3222, jalooc, and som-sm reacted with heart emoji
All reactions
  • 👍 47 reactions
  • 🎉 18 reactions
  • ❤️ 11 reactions
Anders Hejlsberg (ahejlsberg) added 4 commits July 29, 2018 15:14
@ahejlsberg
Homomorphic mapped type support for arrays and tuples
8eb24db
@ahejlsberg
Accept new baselines
df10095
@ahejlsberg
Add tests
32a9ec6
@ahejlsberg
Accept new baselines
efb6e0b
@ahejlsberg
Anders Hejlsberg (ahejlsberg) requested review from Daniel Rosenwasser (DanielRosenwasser), Mohamed Hegazy (mhegazy), Nathan Shively-Sanders (sandersn) and Wesley Wigham (weswigham) July 30, 2018 14:32
sandersn
Nathan Shively-Sanders (sandersn) approved these changes Jul 30, 2018
View reviewed changes

@sandersn Nathan Shively-Sanders (sandersn) left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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
Comment thread src/compiler/checker.ts
// to a union type A | B, we produce { [P in keyof A]: X } | { [P in keyof B]: X }. Furthermore, for
// homomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a
// union type A | undefined, we produce { [P in keyof A]: X } | undefined.
// For a momomorphic mapped type { [P in keyof T]: X }, where T is some type variable, the mapping

@sandersn Nathan Shively-Sanders (sandersn) Jul 30, 2018

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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
Comment thread src/compiler/checker.ts
const elementTypes = map(tupleType.typeArguments || emptyArray, (_, i) =>
instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), i >= minLength, mapper));
const modifiers = getMappedTypeModifiers(mappedType);
const newMinLength = modifiers & MappedTypeModifiers.IncludeOptional ? 0 :

@sandersn Nathan Shively-Sanders (sandersn) Jul 30, 2018

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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
Comment thread src/compiler/checker.ts
if (isMappableType(t)) {
return instantiateAnonymousType(type, createReplacementMapper(typeVariable, t, mapper));
const replacementMapper = createReplacementMapper(typeVariable, t, mapper);
return isArrayType(t) ? createArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) :

@sandersn Nathan Shively-Sanders (sandersn) Jul 30, 2018

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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

@ahejlsberg Anders Hejlsberg (ahejlsberg) Jul 30, 2018

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The isOptional indicates whether a -? modifier on the mapped type should strip undefined from the source type. We want to do that when the source type originates in an optional property, but we also want to do it when the source type is an array element type.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
mhegazy
Mohamed Hegazy (mhegazy) approved these changes Jul 30, 2018
View reviewed changes
@ahejlsberg Anders Hejlsberg (ahejlsberg) added this to the TypeScript 3.1 milestone Jul 31, 2018
@ahejlsberg
Anders Hejlsberg (ahejlsberg) merged commit 4bc7f15 into master Jul 31, 2018
@ahejlsberg
Anders Hejlsberg (ahejlsberg) deleted the mappedTypesArraysTuples branch July 31, 2018 17:54
@ghost ghost mentioned this pull request Aug 1, 2018
Array mapped type change breaks ember array 'get' #26120
Closed
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) mentioned this pull request Aug 1, 2018
Mapped tuple types #25947
Closed
4 tasks done
@jcalz

Joe Calzaretta (jcalz) commented Aug 1, 2018

Copy link
Copy Markdown
Contributor

First: this is awesome.

Next: I know there were questions around still being able to map arrays/tuples like objects if the need arises. Below are some constructs that seem to allow that (PromisifySomeKeysTuple and PromisifyIntersectionTuple); the question is: are they intended or unintended?

type PromisifyNormal<T> = { [K in keyof T]: Promise<T[K]> }
type PromisifyNormalObject = PromisifyNormal<{ a: string, b: number, c: boolean }>
// {a: Promise<string>, b: Promise<number>, c: Promise<boolean>}
type PromisifyNormalTuple = PromisifyNormal<[string, number, boolean]>;
// [Promise<string>, Promise<number>, Promise<boolean>]

type PromisifySomeKeys<T, KT extends keyof T = keyof T> = { [K in KT]: Promise<T[K]> }
type PromisifySomeKeysObject = PromisifySomeKeys<{ a: string, b: number, c: boolean }>
// {a: Promise<string>, b: Promise<number>, c: Promise<boolean>}
type PromisifySomeKeysTuple = PromisifySomeKeys<[string, number, boolean]>;
/* 
type PromisifySomeKeysTuple = {
  [x: number]: Promise<string | number | boolean>;
  "0": Promise<string>;
  "1": Promise<number>;
  "2": Promise<boolean>;
  length: Promise<3>;
  ...
}
*/

type PromisifyIntersectionTuple = PromisifyNormal<[string, number, boolean] & { randomProp: 1234 }>;
/* 
type PromisifyIntersectionTuple = {
  [x: number]: Promise<string | number | boolean>;
  "0": Promise<string>;
  "1": Promise<number>;
  "2": Promise<boolean>;
  length: Promise<3>;
  ...
  randomProp: Promise<1234>;
}
*/
dragomirtitian, IllusionMH, and gtkatakura-bysoft reacted with thumbs up emoji
All reactions
  • 👍 3 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@dead-claudia Claudia Meadows (dead-claudia) mentioned this pull request Aug 2, 2018
Tuple iteration and merging #26058
Open
4 tasks done
@AlCalzone AlCalzone mentioned this pull request Aug 3, 2018
Further improve mapped type support for tuples and arrays (almost complete Promisify<T> inside!) #26190
Open
4 tasks done
@Roaders

Roaders commented Aug 4, 2018

Copy link
Copy Markdown

This is really cool and I actually just asked if this was possible in 3.0 here.

I have had a play with this with the insiders build and it does exactly what I want:

class Maybe<T>{}

type MaybeTuple = [Maybe<string>, Maybe<number>, Maybe<boolean>];

type MaybeType<T> = T extends Maybe<infer MaybeType> ? MaybeType : never;
type MaybeTypes<T> = {[P in keyof T]: MaybeType<T[P]>};

type extractedTypes = MaybeTypes<MaybeTuple>;

my only comment would be that the type of extractedTypes when you mouse over it is:

type extractedTypes = {
    [x: number]: string | number | boolean;
    "0": string;
    "1": number;
    "2": boolean;
    length: {};
    includes: {};
    toString: {};
    toLocaleString: {};
    push: {};
    pop: {};
    concat: {};
    join: {};
    reverse: {};
    shift: {};
    slice: {};
    sort: {};
    splice: {};
    unshift: {};
    indexOf: {};
    lastIndexOf: {};
    every: {};
    some: {};
    forEach: {};
    map: {};
    filter: {};
    reduce: {};
    reduceRight: {};
    entries: {};
    keys: {};
    values: {};
    find: {};
    findIndex: {};
    fill: {};
    copyWithin: {};
}

whereas I would expect [string, number, boolean]

billba, Quramy, chpio, and klesun reacted with thumbs up emoji klesun reacted with eyes emoji
All reactions
  • 👍 4 reactions
  • 👀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Roaders

Roaders commented Aug 4, 2018

Copy link
Copy Markdown

As far as I can tell this PR does not help in the case of the rxjs pipe function:

    pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;
    pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
    pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;
    pipe<A, B, C, D>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>): Observable<D>;
    pipe<A, B, C, D, E>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>): Observable<E>;

here the second type param of one element in the tuple is the first type param of the next element in the tuple.

Is this case currently supported?

reggi reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jcalz Joe Calzaretta (jcalz) mentioned this pull request Aug 7, 2018
Distinguish missing and undefined #13195
Closed
@dragomirtitian

Titian Cernicova-Dragomir (dragomirtitian) commented Aug 15, 2018

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) I've been playing a bit with this and the compiler does seem not recognize the fact that a mapped array type will still be an array type for the purpose of rest parameters. Ex on 3.1.0-dev.20180813 i get this error:

type Promisify<T> = { [P in keyof T]: Promise<T[P]> };
// error:  A rest parameter must be of an array type.
async function  invokeWhenReady<T extends any[], R>(fn : (...a: T) => R, ...a: Promisify<T>) : Promise<R>{
    return null as any;
}

Is this a bug, or design limitation. Will it be addressed in the future ?

bfricka, millsp, csr632, and klesun reacted with thumbs up emoji klesun reacted with eyes emoji
All reactions
  • 👍 4 reactions
  • 👀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jcalz

Joe Calzaretta (jcalz) commented Aug 15, 2018

Copy link
Copy Markdown
Contributor

Titian Cernicova-Dragomir (@dragomirtitian) I think that's being tracked in #26163.

dragomirtitian reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Aug 21, 2018
[@types/ember bug] - ember types are broken in TypeScript 3.1 typed-ember/ember-cli-typescript#246
Closed
[@types/ember] rewrite computed property unwrapping to use infer DefinitelyTyped/DefinitelyTyped#28282
Merged
[RFC] What constitutes a breaking change? typed-ember/ember-cli-typescript#249
Closed
@jack-williams

Jack Williams (jack-williams) commented Aug 28, 2018

Copy link
Copy Markdown
Collaborator

Joe Calzaretta (@jcalz) I don't think that issue fixes the specific case of rest types because they use a different assignment relation. I think the problem is that the rest type checking uses isRestParameterType, which in turn uses assignable relation, not the definitely assignable relation that was fixed.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Aug 28, 2018

Copy link
Copy Markdown
Member Author

Titian Cernicova-Dragomir (@dragomirtitian) Joe Calzaretta (@jcalz) Jack Williams (@jack-williams) The invokeWhenReady example above works with #26676. For example:

declare let ps: Promise<string>;
declare let px: Promise<number[]>;

const r = invokeWhenReady((s, x) => ({ s, x }), ps, px)  // Promise<{ s: string, x: number[] }>
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@dead-claudia Claudia Meadows (dead-claudia) mentioned this pull request Sep 9, 2018
Proposal: Variadic Kinds -- Give specific types to variadic functions #5453
Closed
@masaeedu Asad Saeeduddin (masaeedu) mentioned this pull request Sep 16, 2018
__ #27129
Closed
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 21, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
c5e7c93
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 25, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
f5a2f8a
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 25, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
49148ac
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 29, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
1f72e65
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 3, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
1609645
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 3, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
46f97d8
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 4, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
eb87036
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 6, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
a01608e
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 9, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
b310e35
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 10, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
fbcd07f
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 11, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
f5f43a8
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 12, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
56a62b7
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 12, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
1e81b5f
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 13, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
f4ae733
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 21, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
81677f5
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 22, 2020
@jablko
Mapped type support for array subtypes, like microsoft#26063
6511b3c
@sisisin sisisin (sisisin) mentioned this pull request Aug 8, 2020
Enable Epic#onMany to be called with many arguments typeless-js/typeless#86
Merged
@jcalz Joe Calzaretta (jcalz) mentioned this pull request Aug 16, 2020
Using 'Key in keyof ArrayType' always returns an Array regardles of the value manipulation applied #40069
Open
@Offirmo Offirmo (Offirmo) mentioned this pull request Oct 26, 2020
Suggestion: DeepReadonly<T> type #13923
Open
@insidewhy insidewhy mentioned this pull request Dec 27, 2020
Key remapping breaks tuple support for mapped types #42122
Closed
@trusktr Joe Pea (trusktr) mentioned this pull request Mar 7, 2021
Mapped array/tuple types not always working as expected #43129
Closed
@klesun

Artur Klesun (klesun) commented Nov 26, 2021 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

For anyone who is struggling with prototype properties getting mapped as well (like in Roaders's #26063 (comment)), causing A rest parameter must be of an array type error, I found out that it can be solved by explicitly keeping prototype properties out of boxing:

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 v4.4.4, but seems to require explicit condition since 4.5.2, at least in a more complicated scenario)

rivertam, worstpractice, and WofWca reacted with thumbs up emoji
All reactions
  • 👍 3 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@RyanCavanaugh Ryan Cavanaugh (RyanCavanaugh) mentioned this pull request Mar 22, 2023
In mapped types with key remapping, any property involving a generic type argument is dropped. #53357
Closed
@jedwards1211

Andy Edwards (jedwards1211) commented Nov 8, 2023

Copy link
Copy Markdown

Anders Hejlsberg (@ahejlsberg) it appears this only works on type aliases, rather than any homomorphic mapped type?

type Tuple = [1, 2];
type A<T> = { [K in keyof T]: string };

type WithAlias = A<Tuple> // [string, string]

type WithoutAlias = { [K in keyof Tuple]: string };
/*
  {
    [x: number]: string;
    0: string;
    1: string;
    length: string;
    ...
 */

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 := had been used for TS type aliases.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@RyanCavanaugh

Ryan Cavanaugh (RyanCavanaugh) commented Nov 9, 2023

Copy link
Copy Markdown
Member

The higher-order behavior only applies to generics, so bare object type expressions are never homomorphic; only aliases are.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jedwards1211

Andy Edwards (jedwards1211) commented Nov 9, 2023

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jcalz

Joe Calzaretta (jcalz) commented Nov 9, 2023

Copy link
Copy Markdown
Contributor

See #27995

jedwards1211 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@som-sm Som Shekhar Mukherjee (som-sm) mentioned this pull request Oct 21, 2024
Fix: Behaviour of OptionalKeys when instantiated with primitives and arrays ts-essentials/ts-essentials#414
Merged
1 of 2 tasks
@microsoft Microsoft (microsoft) locked as resolved and limited conversation to collaborators Oct 16, 2025
@typescript-bot TypeScript Bot (typescript-bot) assigned Anders Hejlsberg (ahejlsberg) Oct 16, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@sandersn Nathan Shively-Sanders (sandersn) sandersn approved these changes
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) Awaiting requested review from DanielRosenwasser
@weswigham Wesley Wigham (weswigham) Awaiting requested review from weswigham
+1 more reviewer
@mhegazy Mohamed Hegazy (mhegazy) mhegazy approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@ahejlsberg Anders Hejlsberg (ahejlsberg)

Labels

None yet

Projects

None yet

Milestone

TypeScript 3.1

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

14 participants

@ahejlsberg @jcalz @Roaders @dragomirtitian @jack-williams @Quramy @gund @thorn0 @poying @klesun @jedwards1211 @RyanCavanaugh @sandersn @mhegazy
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.