From 1e6c4bf398ca6368fa89cbfff0ff70da3fce7be8 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:26:28 -0700 Subject: [PATCH 001/116] Add historical coverage: regexp unmatched capture indices Same JS 6.0.3 checker with exact historical before/after standard-library overlays; 0 diagnostics before, two TS2532 after. Library patch changes only the array element union. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61079#issuecomment-2635165231 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../regexpUnmatchedCaptureIndices.errors.txt | 21 +++++++ .../regexpUnmatchedCaptureIndices.symbols | 40 +++++++++++++ .../regexpUnmatchedCaptureIndices.types | 58 +++++++++++++++++++ .../compiler/regexpUnmatchedCaptureIndices.ts | 15 +++++ 4 files changed, 134 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.types create mode 100644 tsc/testdata/tests/cases/compiler/regexpUnmatchedCaptureIndices.ts diff --git a/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.errors.txt b/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.errors.txt new file mode 100644 index 0000000000000..b91c316d0ea26 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.errors.txt @@ -0,0 +1,21 @@ +regexpUnmatchedCaptureIndices.ts(3,5): error TS2532: Object is possibly 'undefined'. +regexpUnmatchedCaptureIndices.ts(4,5): error TS2532: Object is possibly 'undefined'. + + +==== regexpUnmatchedCaptureIndices.ts (2 errors) ==== + const match = /(section)?/d.exec(""); + if (match) { + match.indices![1][0]; + ~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + match.indices![1][1]; + ~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + const indices = match.indices![1]; + if (indices) { + indices[0]; + indices[1]; + } + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.symbols b/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.symbols new file mode 100644 index 0000000000000..07ccf5c27a116 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.symbols @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/regexpUnmatchedCaptureIndices.ts] //// + +=== regexpUnmatchedCaptureIndices.ts === +const match = /(section)?/d.exec(""); +>match : Symbol(match, Decl(regexpUnmatchedCaptureIndices.ts, 0, 5)) +>/(section)?/d.exec : Symbol(RegExp.exec, Decl(lib.es5.d.ts, --, --)) +>exec : Symbol(RegExp.exec, Decl(lib.es5.d.ts, --, --)) + +if (match) { +>match : Symbol(match, Decl(regexpUnmatchedCaptureIndices.ts, 0, 5)) + + match.indices![1][0]; +>match.indices : Symbol(RegExpExecArray.indices, Decl(lib.es2022.regexp.d.ts, --, --)) +>match : Symbol(match, Decl(regexpUnmatchedCaptureIndices.ts, 0, 5)) +>indices : Symbol(RegExpExecArray.indices, Decl(lib.es2022.regexp.d.ts, --, --)) + + match.indices![1][1]; +>match.indices : Symbol(RegExpExecArray.indices, Decl(lib.es2022.regexp.d.ts, --, --)) +>match : Symbol(match, Decl(regexpUnmatchedCaptureIndices.ts, 0, 5)) +>indices : Symbol(RegExpExecArray.indices, Decl(lib.es2022.regexp.d.ts, --, --)) + + const indices = match.indices![1]; +>indices : Symbol(indices, Decl(regexpUnmatchedCaptureIndices.ts, 5, 9)) +>match.indices : Symbol(RegExpExecArray.indices, Decl(lib.es2022.regexp.d.ts, --, --)) +>match : Symbol(match, Decl(regexpUnmatchedCaptureIndices.ts, 0, 5)) +>indices : Symbol(RegExpExecArray.indices, Decl(lib.es2022.regexp.d.ts, --, --)) + + if (indices) { +>indices : Symbol(indices, Decl(regexpUnmatchedCaptureIndices.ts, 5, 9)) + + indices[0]; +>indices : Symbol(indices, Decl(regexpUnmatchedCaptureIndices.ts, 5, 9)) +>0 : Symbol(0) + + indices[1]; +>indices : Symbol(indices, Decl(regexpUnmatchedCaptureIndices.ts, 5, 9)) +>1 : Symbol(1) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.types b/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.types new file mode 100644 index 0000000000000..d5926ef2c568b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpUnmatchedCaptureIndices.types @@ -0,0 +1,58 @@ +//// [tests/cases/compiler/regexpUnmatchedCaptureIndices.ts] //// + +=== regexpUnmatchedCaptureIndices.ts === +const match = /(section)?/d.exec(""); +>match : RegExpExecArray | null +>/(section)?/d.exec("") : RegExpExecArray | null +>/(section)?/d.exec : (string: string) => RegExpExecArray | null +>/(section)?/d : RegExp +>exec : (string: string) => RegExpExecArray | null +>"" : "" + +if (match) { +>match : RegExpExecArray | null + + match.indices![1][0]; +>match.indices![1][0] : number +>match.indices![1] : [number, number] | undefined +>match.indices! : RegExpIndicesArray +>match.indices : RegExpIndicesArray | undefined +>match : RegExpExecArray +>indices : RegExpIndicesArray | undefined +>1 : 1 +>0 : 0 + + match.indices![1][1]; +>match.indices![1][1] : number +>match.indices![1] : [number, number] | undefined +>match.indices! : RegExpIndicesArray +>match.indices : RegExpIndicesArray | undefined +>match : RegExpExecArray +>indices : RegExpIndicesArray | undefined +>1 : 1 +>1 : 1 + + const indices = match.indices![1]; +>indices : [number, number] | undefined +>match.indices![1] : [number, number] | undefined +>match.indices! : RegExpIndicesArray +>match.indices : RegExpIndicesArray | undefined +>match : RegExpExecArray +>indices : RegExpIndicesArray | undefined +>1 : 1 + + if (indices) { +>indices : [number, number] | undefined + + indices[0]; +>indices[0] : number +>indices : [number, number] +>0 : 0 + + indices[1]; +>indices[1] : number +>indices : [number, number] +>1 : 1 + } +} + diff --git a/tsc/testdata/tests/cases/compiler/regexpUnmatchedCaptureIndices.ts b/tsc/testdata/tests/cases/compiler/regexpUnmatchedCaptureIndices.ts new file mode 100644 index 0000000000000..44a65b567901b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/regexpUnmatchedCaptureIndices.ts @@ -0,0 +1,15 @@ +// @strict: true +// @target: es2022 +// @noEmit: true + +const match = /(section)?/d.exec(""); +if (match) { + match.indices![1][0]; + match.indices![1][1]; + + const indices = match.indices![1]; + if (indices) { + indices[0]; + indices[1]; + } +} From 139d4980d3682f29dc317faf8969aa288e655226 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:26:32 -0700 Subject: [PATCH 002/116] Add historical coverage: distributed recursive mapped index Exact native source builds 0b832e12235cc3db14a4be6501827c2f8a8a8569 and bb209ac1c0a8c1b1b8f74da1968e88be0bf1f2cd; 0 diagnostics before, TS2344 and TS2536 after. Origin: https://redirect.github.com/microsoft/TypeScript/pull/64237#issuecomment-5625419140 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../distributedRecursiveMappedType.errors.txt | 17 ++++++++++++++ .../distributedRecursiveMappedType.symbols | 22 +++++++++++++++++++ .../distributedRecursiveMappedType.types | 9 ++++++++ .../distributedRecursiveMappedType.ts | 5 +++++ 4 files changed, 53 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.types create mode 100644 tsc/testdata/tests/cases/compiler/distributedRecursiveMappedType.ts diff --git a/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.errors.txt b/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.errors.txt new file mode 100644 index 0000000000000..66c57a4a4b4b6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.errors.txt @@ -0,0 +1,17 @@ +distributedRecursiveMappedType.ts(2,49): error TS2344: Type 'Input[Key]' does not satisfy the constraint 'Shape[Key]'. + Type 'Input' is not assignable to type 'Shape'. + 'Input' is only assignable to the non-distributed 'Shape', but 'Shape' has been distributed here. +distributedRecursiveMappedType.ts(2,49): error TS2536: Type 'Key' cannot be used to index type 'Input'. + + +==== distributedRecursiveMappedType.ts (2 errors) ==== + type Exact = Shape extends Shape + ? { [Key in keyof Shape]: Exact } + ~~~~~~~~~~ +!!! error TS2344: Type 'Input[Key]' does not satisfy the constraint 'Shape[Key]'. +!!! error TS2344: Type 'Input' is not assignable to type 'Shape'. +!!! error TS2344: 'Input' is only assignable to the non-distributed 'Shape', but 'Shape' has been distributed here. + ~~~~~~~~~~ +!!! error TS2536: Type 'Key' cannot be used to index type 'Input'. + : never; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.symbols b/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.symbols new file mode 100644 index 0000000000000..205107931779c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/distributedRecursiveMappedType.ts] //// + +=== distributedRecursiveMappedType.ts === +type Exact = Shape extends Shape +>Exact : Symbol(Exact, Decl(distributedRecursiveMappedType.ts, 0, 0)) +>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11)) +>Input : Symbol(Input, Decl(distributedRecursiveMappedType.ts, 0, 17)) +>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11)) +>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11)) +>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11)) + + ? { [Key in keyof Shape]: Exact } +>Key : Symbol(Key, Decl(distributedRecursiveMappedType.ts, 1, 9)) +>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11)) +>Exact : Symbol(Exact, Decl(distributedRecursiveMappedType.ts, 0, 0)) +>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11)) +>Key : Symbol(Key, Decl(distributedRecursiveMappedType.ts, 1, 9)) +>Input : Symbol(Input, Decl(distributedRecursiveMappedType.ts, 0, 17)) +>Key : Symbol(Key, Decl(distributedRecursiveMappedType.ts, 1, 9)) + + : never; + diff --git a/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.types b/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.types new file mode 100644 index 0000000000000..06d9da380ea4b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/distributedRecursiveMappedType.types @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/distributedRecursiveMappedType.ts] //// + +=== distributedRecursiveMappedType.ts === +type Exact = Shape extends Shape +>Exact : Exact + + ? { [Key in keyof Shape]: Exact } + : never; + diff --git a/tsc/testdata/tests/cases/compiler/distributedRecursiveMappedType.ts b/tsc/testdata/tests/cases/compiler/distributedRecursiveMappedType.ts new file mode 100644 index 0000000000000..a3084046746be --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/distributedRecursiveMappedType.ts @@ -0,0 +1,5 @@ +// @noEmit: true + +type Exact = Shape extends Shape + ? { [Key in keyof Shape]: Exact } + : never; From 1dfed632cdc5e0e6248318cd1e37c7237524b5a4 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:26:35 -0700 Subject: [PATCH 003/116] Add historical coverage: conditional generic prompt inference Exact native source builds: base 0b832e12235cc3db14a4be6501827c2f8a8a8569 clean; initial 6e4385601c885924efedea6d94383205ed210277 TS2345 plus TS2322/2558; merged bb209ac1c0a8c1b1b8f74da1968e88be0bf1f2cd clean. Origin: https://redirect.github.com/microsoft/TypeScript/pull/64237#issuecomment-5625419140 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../conditionalPromptInference.symbols | 48 ++++++++++++++++++ .../compiler/conditionalPromptInference.types | 50 +++++++++++++++++++ .../compiler/conditionalPromptInference.ts | 14 ++++++ 3 files changed, 112 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalPromptInference.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalPromptInference.types create mode 100644 tsc/testdata/tests/cases/compiler/conditionalPromptInference.ts diff --git a/tsc/testdata/baselines/reference/compiler/conditionalPromptInference.symbols b/tsc/testdata/baselines/reference/compiler/conditionalPromptInference.symbols new file mode 100644 index 0000000000000..2d4ea4e93c146 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalPromptInference.symbols @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/conditionalPromptInference.ts] //// + +=== conditionalPromptInference.ts === +declare function createPrompt( +>createPrompt : Symbol(createPrompt, Decl(conditionalPromptInference.ts, 0, 0)) +>Value : Symbol(Value, Decl(conditionalPromptInference.ts, 0, 30)) +>Config : Symbol(Config, Decl(conditionalPromptInference.ts, 0, 36)) + + view: (config: Config, done: (value: Value) => void) => void, +>view : Symbol(view, Decl(conditionalPromptInference.ts, 0, 45)) +>config : Symbol(config, Decl(conditionalPromptInference.ts, 1, 11)) +>Config : Symbol(Config, Decl(conditionalPromptInference.ts, 0, 36)) +>done : Symbol(done, Decl(conditionalPromptInference.ts, 1, 26)) +>value : Symbol(value, Decl(conditionalPromptInference.ts, 1, 34)) +>Value : Symbol(Value, Decl(conditionalPromptInference.ts, 0, 30)) + +): (config: Config) => Value; +>config : Symbol(config, Decl(conditionalPromptInference.ts, 2, 4)) +>Config : Symbol(Config, Decl(conditionalPromptInference.ts, 0, 36)) +>Value : Symbol(Value, Decl(conditionalPromptInference.ts, 0, 30)) + +const numberPrompt = createPrompt(( +>numberPrompt : Symbol(numberPrompt, Decl(conditionalPromptInference.ts, 4, 5)) +>createPrompt : Symbol(createPrompt, Decl(conditionalPromptInference.ts, 0, 0)) +>Required : Symbol(Required, Decl(conditionalPromptInference.ts, 4, 35)) + + config: { required?: Required }, +>config : Symbol(config, Decl(conditionalPromptInference.ts, 4, 61)) +>required : Symbol(required, Decl(conditionalPromptInference.ts, 5, 13)) +>Required : Symbol(Required, Decl(conditionalPromptInference.ts, 4, 35)) + + done: (value: Required extends true ? number : number | undefined) => void, +>done : Symbol(done, Decl(conditionalPromptInference.ts, 5, 36)) +>value : Symbol(value, Decl(conditionalPromptInference.ts, 6, 11)) +>Required : Symbol(Required, Decl(conditionalPromptInference.ts, 4, 35)) + +) => {}); + +const required: number = numberPrompt({ required: true }); +>required : Symbol(required, Decl(conditionalPromptInference.ts, 9, 5)) +>numberPrompt : Symbol(numberPrompt, Decl(conditionalPromptInference.ts, 4, 5)) +>required : Symbol(required, Decl(conditionalPromptInference.ts, 9, 45)) + +const optional: number | undefined = numberPrompt({ required: false }); +>optional : Symbol(optional, Decl(conditionalPromptInference.ts, 10, 5)) +>numberPrompt : Symbol(numberPrompt, Decl(conditionalPromptInference.ts, 4, 5)) +>required : Symbol(required, Decl(conditionalPromptInference.ts, 10, 58)) + diff --git a/tsc/testdata/baselines/reference/compiler/conditionalPromptInference.types b/tsc/testdata/baselines/reference/compiler/conditionalPromptInference.types new file mode 100644 index 0000000000000..d1457bdeff455 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalPromptInference.types @@ -0,0 +1,50 @@ +//// [tests/cases/compiler/conditionalPromptInference.ts] //// + +=== conditionalPromptInference.ts === +declare function createPrompt( +>createPrompt : (view: (config: Config, done: (value: Value) => void) => void) => (config: Config) => Value + + view: (config: Config, done: (value: Value) => void) => void, +>view : (config: Config, done: (value: Value) => void) => void +>config : Config +>done : (value: Value) => void +>value : Value + +): (config: Config) => Value; +>config : Config + +const numberPrompt = createPrompt(( +>numberPrompt : (config: { required?: Required; }) => Required extends true ? number : number | undefined +>createPrompt(( config: { required?: Required }, done: (value: Required extends true ? number : number | undefined) => void,) => {}) : (config: { required?: Required; }) => Required extends true ? number : number | undefined +>createPrompt : (view: (config: Config, done: (value: Value) => void) => void) => (config: Config) => Value +>( config: { required?: Required }, done: (value: Required extends true ? number : number | undefined) => void,) => {} : (config: { required?: Required; }, done: (value: Required extends true ? number : number | undefined) => void) => void + + config: { required?: Required }, +>config : { required?: Required; } +>required : Required | undefined + + done: (value: Required extends true ? number : number | undefined) => void, +>done : (value: Required extends true ? number : number | undefined) => void +>value : Required extends true ? number : number | undefined +>true : true + +) => {}); + +const required: number = numberPrompt({ required: true }); +>required : number +>numberPrompt({ required: true }) : number +>numberPrompt : (config: { required?: Required; }) => Required extends true ? number : number | undefined +>true : true +>{ required: true } : { required: true; } +>required : true +>true : true + +const optional: number | undefined = numberPrompt({ required: false }); +>optional : number | undefined +>numberPrompt({ required: false }) : number | undefined +>numberPrompt : (config: { required?: Required; }) => Required extends true ? number : number | undefined +>false : false +>{ required: false } : { required: false; } +>required : false +>false : false + diff --git a/tsc/testdata/tests/cases/compiler/conditionalPromptInference.ts b/tsc/testdata/tests/cases/compiler/conditionalPromptInference.ts new file mode 100644 index 0000000000000..04a6b59a10d52 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/conditionalPromptInference.ts @@ -0,0 +1,14 @@ +// @strict: true +// @noEmit: true + +declare function createPrompt( + view: (config: Config, done: (value: Value) => void) => void, +): (config: Config) => Value; + +const numberPrompt = createPrompt(( + config: { required?: Required }, + done: (value: Required extends true ? number : number | undefined) => void, +) => {}); + +const required: number = numberPrompt({ required: true }); +const optional: number | undefined = numberPrompt({ required: false }); From 7c943d65ffede69d001bf1b54f216c6f87f0049b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:26:38 -0700 Subject: [PATCH 004/116] Add historical coverage: contextual return spread pick inference Exact JS checker source builds: base 479285d0ac293c35a926508d17f0bb5eca7e0303 clean; head 77331a98268ee50b92d112311533860fc54daddc TS2741. Minimal author reduction from comment2995133352 preserves missing contextual return properties. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61913#issuecomment-2994475582 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ontextualReturnSpreadPickInference.symbols | 47 +++++++++++++++++++ .../contextualReturnSpreadPickInference.types | 40 ++++++++++++++++ .../contextualReturnSpreadPickInference.ts | 16 +++++++ 3 files changed, 103 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.types create mode 100644 tsc/testdata/tests/cases/compiler/contextualReturnSpreadPickInference.ts diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.symbols b/tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.symbols new file mode 100644 index 0000000000000..9dbfd185aaa27 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.symbols @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/contextualReturnSpreadPickInference.ts] //// + +=== contextualReturnSpreadPickInference.ts === +type Many = T | readonly T[]; +>Many : Symbol(Many, Decl(contextualReturnSpreadPickInference.ts, 0, 0)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 0, 10)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 0, 10)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 0, 10)) + +declare function pick( +>pick : Symbol(pick, Decl(contextualReturnSpreadPickInference.ts, 0, 32)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22)) +>Key : Symbol(Key, Decl(contextualReturnSpreadPickInference.ts, 1, 39)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22)) + + object: T, +>object : Symbol(object, Decl(contextualReturnSpreadPickInference.ts, 1, 61)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22)) + + ...props: Many[] +>props : Symbol(props, Decl(contextualReturnSpreadPickInference.ts, 2, 14)) +>Many : Symbol(Many, Decl(contextualReturnSpreadPickInference.ts, 0, 0)) +>Key : Symbol(Key, Decl(contextualReturnSpreadPickInference.ts, 1, 39)) + +): Pick; +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22)) +>Key : Symbol(Key, Decl(contextualReturnSpreadPickInference.ts, 1, 39)) + +async function getPage(page: any): Promise<{ title: string; intro: string }> { +>getPage : Symbol(getPage, Decl(contextualReturnSpreadPickInference.ts, 4, 16)) +>page : Symbol(page, Decl(contextualReturnSpreadPickInference.ts, 6, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>title : Symbol(title, Decl(contextualReturnSpreadPickInference.ts, 6, 44)) +>intro : Symbol(intro, Decl(contextualReturnSpreadPickInference.ts, 6, 59)) + + return { + title: "", +>title : Symbol(title, Decl(contextualReturnSpreadPickInference.ts, 7, 12)) + + ...pick(page, ["intro"]), +>pick : Symbol(pick, Decl(contextualReturnSpreadPickInference.ts, 0, 32)) +>page : Symbol(page, Decl(contextualReturnSpreadPickInference.ts, 6, 23)) + + }; +} + diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.types b/tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.types new file mode 100644 index 0000000000000..a7f6f7edc5c08 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnSpreadPickInference.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/contextualReturnSpreadPickInference.ts] //// + +=== contextualReturnSpreadPickInference.ts === +type Many = T | readonly T[]; +>Many : Many + +declare function pick( +>pick : (object: T, ...props: Many[]) => Pick + + object: T, +>object : T + + ...props: Many[] +>props : Many[] + +): Pick; + +async function getPage(page: any): Promise<{ title: string; intro: string }> { +>getPage : (page: any) => Promise<{ title: string; intro: string; }> +>page : any +>title : string +>intro : string + + return { +>{ title: "", ...pick(page, ["intro"]), } : { title: string; intro: any; } + + title: "", +>title : string +>"" : "" + + ...pick(page, ["intro"]), +>pick(page, ["intro"]) : Pick +>pick : (object: T, ...props: Many[]) => Pick +>page : any +>["intro"] : "intro"[] +>"intro" : "intro" + + }; +} + diff --git a/tsc/testdata/tests/cases/compiler/contextualReturnSpreadPickInference.ts b/tsc/testdata/tests/cases/compiler/contextualReturnSpreadPickInference.ts new file mode 100644 index 0000000000000..3e104e442eb27 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualReturnSpreadPickInference.ts @@ -0,0 +1,16 @@ +// @strict: true +// @target: es2015 +// @noEmit: true + +type Many = T | readonly T[]; +declare function pick( + object: T, + ...props: Many[] +): Pick; + +async function getPage(page: any): Promise<{ title: string; intro: string }> { + return { + title: "", + ...pick(page, ["intro"]), + }; +} From 6c1287b5d210cd9d5e8f7a60796340a03b27f0b7 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:26:42 -0700 Subject: [PATCH 005/116] Add historical coverage: websocket array buffer like restriction Fixed JS6.0.3 checker with exact historical DOM overlays: ee09569714e1414557f072909d7bbda0b29b8d54 clean; e1b5d2986c627ffce0bd0f616c8200248bc8b67c TS2345. Both Uint8Array and ArrayBufferView report forms share the rejected ArrayBufferLike buffer. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62730#issuecomment-3501279525 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../webSocketSendArrayBufferLike.errors.txt | 19 ++++++++++++++ .../webSocketSendArrayBufferLike.symbols | 23 +++++++++++++++++ .../webSocketSendArrayBufferLike.types | 25 +++++++++++++++++++ .../compiler/webSocketSendArrayBufferLike.ts | 8 ++++++ 4 files changed, 75 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.types create mode 100644 tsc/testdata/tests/cases/compiler/webSocketSendArrayBufferLike.ts diff --git a/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.errors.txt b/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.errors.txt new file mode 100644 index 0000000000000..2f8c553db0fe6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.errors.txt @@ -0,0 +1,19 @@ +webSocketSendArrayBufferLike.ts(3,13): error TS2345: Argument of type 'Uint8Array' is not assignable to parameter of type 'string | Blob | BufferSource'. + Type 'Uint8Array' is not assignable to type 'ArrayBufferView'. + Types of property 'buffer' are incompatible. + Type 'ArrayBufferLike' is not assignable to type 'ArrayBuffer'. + Type 'SharedArrayBuffer' is missing the following properties from type 'ArrayBuffer': resizable, resize, detached, transfer, transferToFixedLength + + +==== webSocketSendArrayBufferLike.ts (1 errors) ==== + declare const socket: WebSocket; + declare const bytes: Uint8Array; + socket.send(bytes); + ~~~~~ +!!! error TS2345: Argument of type 'Uint8Array' is not assignable to parameter of type 'string | Blob | BufferSource'. +!!! error TS2345: Type 'Uint8Array' is not assignable to type 'ArrayBufferView'. +!!! error TS2345: Types of property 'buffer' are incompatible. +!!! error TS2345: Type 'ArrayBufferLike' is not assignable to type 'ArrayBuffer'. +!!! error TS2345: Type 'SharedArrayBuffer' is missing the following properties from type 'ArrayBuffer': resizable, resize, detached, transfer, transferToFixedLength + socket.send(new Uint8Array(8)); + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.symbols b/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.symbols new file mode 100644 index 0000000000000..0149c657ab078 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/webSocketSendArrayBufferLike.ts] //// + +=== webSocketSendArrayBufferLike.ts === +declare const socket: WebSocket; +>socket : Symbol(socket, Decl(webSocketSendArrayBufferLike.ts, 0, 13)) +>WebSocket : Symbol(WebSocket, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +declare const bytes: Uint8Array; +>bytes : Symbol(bytes, Decl(webSocketSendArrayBufferLike.ts, 1, 13)) +>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 3 more) + +socket.send(bytes); +>socket.send : Symbol(WebSocket.send, Decl(lib.dom.d.ts, --, --)) +>socket : Symbol(socket, Decl(webSocketSendArrayBufferLike.ts, 0, 13)) +>send : Symbol(WebSocket.send, Decl(lib.dom.d.ts, --, --)) +>bytes : Symbol(bytes, Decl(webSocketSendArrayBufferLike.ts, 1, 13)) + +socket.send(new Uint8Array(8)); +>socket.send : Symbol(WebSocket.send, Decl(lib.dom.d.ts, --, --)) +>socket : Symbol(socket, Decl(webSocketSendArrayBufferLike.ts, 0, 13)) +>send : Symbol(WebSocket.send, Decl(lib.dom.d.ts, --, --)) +>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 3 more) + diff --git a/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.types b/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.types new file mode 100644 index 0000000000000..20b70cfd5afe5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/webSocketSendArrayBufferLike.types @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/webSocketSendArrayBufferLike.ts] //// + +=== webSocketSendArrayBufferLike.ts === +declare const socket: WebSocket; +>socket : WebSocket + +declare const bytes: Uint8Array; +>bytes : Uint8Array + +socket.send(bytes); +>socket.send(bytes) : void +>socket.send : (data: BufferSource | Blob | string) => void +>socket : WebSocket +>send : (data: BufferSource | Blob | string) => void +>bytes : Uint8Array + +socket.send(new Uint8Array(8)); +>socket.send(new Uint8Array(8)) : void +>socket.send : (data: BufferSource | Blob | string) => void +>socket : WebSocket +>send : (data: BufferSource | Blob | string) => void +>new Uint8Array(8) : Uint8Array +>Uint8Array : Uint8ArrayConstructor +>8 : 8 + diff --git a/tsc/testdata/tests/cases/compiler/webSocketSendArrayBufferLike.ts b/tsc/testdata/tests/cases/compiler/webSocketSendArrayBufferLike.ts new file mode 100644 index 0000000000000..f323f8109bffa --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/webSocketSendArrayBufferLike.ts @@ -0,0 +1,8 @@ +// @strict: true +// @lib: es2024, dom +// @noEmit: true + +declare const socket: WebSocket; +declare const bytes: Uint8Array; +socket.send(bytes); +socket.send(new Uint8Array(8)); From f40d8af2447198a4e95f554c0c15e099c53b947e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:26:45 -0700 Subject: [PATCH 006/116] Add historical coverage: fetch replacement input compatibility Fixed JS6.0.3 checker with exact DOM and DOM.Iterable: base efbf3b5067547539c9cf8331d51943543c8bc91a clean; initial 0afb2fd38fa96fb0a13d68da36acf347fb9b0b2f TS2322/2345 from added Location input; final 30e4958268d66214425f6478cb412de017cc3fa9 clean. Overload-extraction/mock and discriminant-url forms remain pending separate review. Origin: https://redirect.github.com/microsoft/TypeScript/pull/64604#issuecomment-5959842795 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...fetchReplacementInputCompatibility.symbols | 27 +++++++++++++++++++ .../fetchReplacementInputCompatibility.types | 22 +++++++++++++++ .../fetchReplacementInputCompatibility.ts | 9 +++++++ 3 files changed, 58 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.types create mode 100644 tsc/testdata/tests/cases/compiler/fetchReplacementInputCompatibility.ts diff --git a/tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.symbols b/tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.symbols new file mode 100644 index 0000000000000..4930c095e7e3d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/fetchReplacementInputCompatibility.ts] //// + +=== fetchReplacementInputCompatibility.ts === +declare const fetchReplacement: (input: string | URL | Request, init?: RequestInit) => Promise; +>fetchReplacement : Symbol(fetchReplacement, Decl(fetchReplacementInputCompatibility.ts, 0, 13)) +>input : Symbol(input, Decl(fetchReplacementInputCompatibility.ts, 0, 33)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>Request : Symbol(Request, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>init : Symbol(init, Decl(fetchReplacementInputCompatibility.ts, 0, 63)) +>RequestInit : Symbol(RequestInit, Decl(lib.dom.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Response : Symbol(Response, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +const replacement: typeof fetch = fetchReplacement; +>replacement : Symbol(replacement, Decl(fetchReplacementInputCompatibility.ts, 1, 5)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>fetchReplacement : Symbol(fetchReplacement, Decl(fetchReplacementInputCompatibility.ts, 0, 13)) + +declare const input: Parameters[0]; +>input : Symbol(input, Decl(fetchReplacementInputCompatibility.ts, 3, 13)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) + +fetchReplacement(input); +>fetchReplacement : Symbol(fetchReplacement, Decl(fetchReplacementInputCompatibility.ts, 0, 13)) +>input : Symbol(input, Decl(fetchReplacementInputCompatibility.ts, 3, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.types b/tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.types new file mode 100644 index 0000000000000..cd8a377e15001 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/fetchReplacementInputCompatibility.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/fetchReplacementInputCompatibility.ts] //// + +=== fetchReplacementInputCompatibility.ts === +declare const fetchReplacement: (input: string | URL | Request, init?: RequestInit) => Promise; +>fetchReplacement : (input: string | URL | Request, init?: RequestInit) => Promise +>input : string | Request | URL +>init : RequestInit | undefined + +const replacement: typeof fetch = fetchReplacement; +>replacement : (input: RequestInfo | URL, init?: RequestInit) => Promise +>fetch : (input: RequestInfo | URL, init?: RequestInit) => Promise +>fetchReplacement : (input: string | URL | Request, init?: RequestInit) => Promise + +declare const input: Parameters[0]; +>input : URL | RequestInfo +>fetch : (input: RequestInfo | URL, init?: RequestInit) => Promise + +fetchReplacement(input); +>fetchReplacement(input) : Promise +>fetchReplacement : (input: string | URL | Request, init?: RequestInit) => Promise +>input : URL | RequestInfo + diff --git a/tsc/testdata/tests/cases/compiler/fetchReplacementInputCompatibility.ts b/tsc/testdata/tests/cases/compiler/fetchReplacementInputCompatibility.ts new file mode 100644 index 0000000000000..2a8eced90d7c0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/fetchReplacementInputCompatibility.ts @@ -0,0 +1,9 @@ +// @strict: true +// @lib: es2015,dom +// @noEmit: true + +declare const fetchReplacement: (input: string | URL | Request, init?: RequestInit) => Promise; +const replacement: typeof fetch = fetchReplacement; + +declare const input: Parameters[0]; +fetchReplacement(input); From c2d4b7256727ac74efefa0de52f2a68f42086b50 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:28:02 -0700 Subject: [PATCH 007/116] Add historical coverage: css style iterable compatibility Fixed JS6.0.3 checker with paired exact DOM and DOM.Iterable: base 5f183ad73dc1500209619cf52e174c45d73f8617 clean; intermediate c3fb110853c86c7ca7012944c46a620e45219149 TS2741/2488; final 2f3ef24028cab2ff6b5961db8f446d2bf721181d clean. Separate initial property loss is proven already-covered by divergentAccessorsTypes6. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62496#issuecomment-3353823848 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../cssStyleDeclarationCompatibility.symbols | 19 +++++++++++++++++++ .../cssStyleDeclarationCompatibility.types | 19 +++++++++++++++++++ .../cssStyleDeclarationCompatibility.ts | 8 ++++++++ 3 files changed, 46 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.types create mode 100644 tsc/testdata/tests/cases/compiler/cssStyleDeclarationCompatibility.ts diff --git a/tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.symbols b/tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.symbols new file mode 100644 index 0000000000000..8707bc5102cfc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/cssStyleDeclarationCompatibility.ts] //// + +=== cssStyleDeclarationCompatibility.ts === +declare const element: HTMLElement; +>element : Symbol(element, Decl(cssStyleDeclarationCompatibility.ts, 0, 13)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +const style: CSSStyleDeclaration = element.style; +>style : Symbol(style, Decl(cssStyleDeclarationCompatibility.ts, 1, 5)) +>CSSStyleDeclaration : Symbol(CSSStyleDeclaration, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>element.style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>element : Symbol(element, Decl(cssStyleDeclarationCompatibility.ts, 0, 13)) +>style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +[...element.style]; +>element.style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>element : Symbol(element, Decl(cssStyleDeclarationCompatibility.ts, 0, 13)) +>style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.types b/tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.types new file mode 100644 index 0000000000000..4a92523a67a2b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/cssStyleDeclarationCompatibility.types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/cssStyleDeclarationCompatibility.ts] //// + +=== cssStyleDeclarationCompatibility.ts === +declare const element: HTMLElement; +>element : HTMLElement + +const style: CSSStyleDeclaration = element.style; +>style : CSSStyleDeclaration +>element.style : CSSStyleDeclaration +>element : HTMLElement +>style : CSSStyleDeclaration + +[...element.style]; +>[...element.style] : string[] +>...element.style : string +>element.style : CSSStyleDeclaration +>element : HTMLElement +>style : CSSStyleDeclaration + diff --git a/tsc/testdata/tests/cases/compiler/cssStyleDeclarationCompatibility.ts b/tsc/testdata/tests/cases/compiler/cssStyleDeclarationCompatibility.ts new file mode 100644 index 0000000000000..8d8f4172bdedf --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/cssStyleDeclarationCompatibility.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es2015 +// @lib: es2015, dom, dom.iterable +// @noEmit: true + +declare const element: HTMLElement; +const style: CSSStyleDeclaration = element.style; +[...element.style]; From 007631c0526ebda623847f2c75a6f54cbadf9fa9 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:35:18 -0700 Subject: [PATCH 008/116] Add historical coverage: strict supertype schema Exact JS5.9 source builds and original libraries: base 479285d0ac293c35a926508d17f0bb5eca7e0303, initial b7439c1baf62f9ce18cde8ae8ec455f64b29ec15, final cb554a834ee17236acb2d34f545b14ab43b68f8e; current native a0a0ff55cab4a1f81b7123ab219c97a2f1ed703d. Diagnostic codes before=none, initial=2339, final=2339, current=2339. Covariant callback-result inference chooses the empty object as a strict supertype of a string-indexed Schema interface, losing indexed properties. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61903#issuecomment-2988696289 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/strictSupertypeSchema.errors.txt | 16 ++++++++++ .../compiler/strictSupertypeSchema.symbols | 29 ++++++++++++++++++ .../compiler/strictSupertypeSchema.types | 30 +++++++++++++++++++ .../cases/compiler/strictSupertypeSchema.ts | 12 ++++++++ 4 files changed, 87 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.types create mode 100644 tsc/testdata/tests/cases/compiler/strictSupertypeSchema.ts diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.errors.txt b/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.errors.txt new file mode 100644 index 0000000000000..e0e94f8a7e4e4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.errors.txt @@ -0,0 +1,16 @@ +strictSupertypeSchema.ts(9,8): error TS2339: Property '$ref' does not exist on type '{}'. + + +==== strictSupertypeSchema.ts (1 errors) ==== + interface Schema { + [name: string]: any; + } + + declare function choose(...callbacks: (() => Result)[]): Result; + declare const schema: Schema; + + const result = choose(() => ({}), () => schema); + result.$ref; + ~~~~ +!!! error TS2339: Property '$ref' does not exist on type '{}'. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.symbols b/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.symbols new file mode 100644 index 0000000000000..cd264c4627775 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/strictSupertypeSchema.ts] //// + +=== strictSupertypeSchema.ts === +interface Schema { +>Schema : Symbol(Schema, Decl(strictSupertypeSchema.ts, 0, 0)) + + [name: string]: any; +>name : Symbol(name, Decl(strictSupertypeSchema.ts, 1, 5)) +} + +declare function choose(...callbacks: (() => Result)[]): Result; +>choose : Symbol(choose, Decl(strictSupertypeSchema.ts, 2, 1)) +>Result : Symbol(Result, Decl(strictSupertypeSchema.ts, 4, 24)) +>callbacks : Symbol(callbacks, Decl(strictSupertypeSchema.ts, 4, 32)) +>Result : Symbol(Result, Decl(strictSupertypeSchema.ts, 4, 24)) +>Result : Symbol(Result, Decl(strictSupertypeSchema.ts, 4, 24)) + +declare const schema: Schema; +>schema : Symbol(schema, Decl(strictSupertypeSchema.ts, 5, 13)) +>Schema : Symbol(Schema, Decl(strictSupertypeSchema.ts, 0, 0)) + +const result = choose(() => ({}), () => schema); +>result : Symbol(result, Decl(strictSupertypeSchema.ts, 7, 5)) +>choose : Symbol(choose, Decl(strictSupertypeSchema.ts, 2, 1)) +>schema : Symbol(schema, Decl(strictSupertypeSchema.ts, 5, 13)) + +result.$ref; +>result : Symbol(result, Decl(strictSupertypeSchema.ts, 7, 5)) + diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.types b/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.types new file mode 100644 index 0000000000000..bf7ca8120d85f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeSchema.types @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/strictSupertypeSchema.ts] //// + +=== strictSupertypeSchema.ts === +interface Schema { + [name: string]: any; +>name : string +} + +declare function choose(...callbacks: (() => Result)[]): Result; +>choose : (...callbacks: (() => Result)[]) => Result +>callbacks : (() => Result)[] + +declare const schema: Schema; +>schema : Schema + +const result = choose(() => ({}), () => schema); +>result : {} +>choose(() => ({}), () => schema) : {} +>choose : (...callbacks: (() => Result)[]) => Result +>() => ({}) : () => {} +>({}) : {} +>{} : {} +>() => schema : () => Schema +>schema : Schema + +result.$ref; +>result.$ref : any +>result : {} +>$ref : any + diff --git a/tsc/testdata/tests/cases/compiler/strictSupertypeSchema.ts b/tsc/testdata/tests/cases/compiler/strictSupertypeSchema.ts new file mode 100644 index 0000000000000..ce8bab5d9368d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/strictSupertypeSchema.ts @@ -0,0 +1,12 @@ +// @strict: true +// @noEmit: true + +interface Schema { + [name: string]: any; +} + +declare function choose(...callbacks: (() => Result)[]): Result; +declare const schema: Schema; + +const result = choose(() => ({}), () => schema); +result.$ref; From 03bb75f752fa922ad51d32e5e39ea01528c0436b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:35:22 -0700 Subject: [PATCH 009/116] Add historical coverage: strict supertype injection Exact JS5.9 source builds and original libraries: base 479285d0ac293c35a926508d17f0bb5eca7e0303, initial b7439c1baf62f9ce18cde8ae8ec455f64b29ec15, final cb554a834ee17236acb2d34f545b14ab43b68f8e; current native a0a0ff55cab4a1f81b7123ab219c97a2f1ed703d. Diagnostic codes before=none, initial=2741, final=none, current=none. Phantom symbol-key inference combines a readonly override of a generic getter/setter reference with a generic any fallback. Strict-only candidate selection rejects the fallback. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61903#issuecomment-2988696289 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/strictSupertypeInjection.symbols | 70 +++++++++++++++++++ .../compiler/strictSupertypeInjection.types | 46 ++++++++++++ .../compiler/strictSupertypeInjection.ts | 19 +++++ 3 files changed, 135 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.types create mode 100644 tsc/testdata/tests/cases/compiler/strictSupertypeInjection.ts diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.symbols b/tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.symbols new file mode 100644 index 0000000000000..5f922fa38b7f6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.symbols @@ -0,0 +1,70 @@ +//// [tests/cases/compiler/strictSupertypeInjection.ts] //// + +=== strictSupertypeInjection.ts === +interface Reference { +>Reference : Symbol(Reference, Decl(strictSupertypeInjection.ts, 0, 0)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 0, 20)) + + get value(): Value; +>value : Symbol(Reference.value, Decl(strictSupertypeInjection.ts, 0, 28), Decl(strictSupertypeInjection.ts, 1, 23)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 0, 20)) + + set value(value: Value); +>value : Symbol(Reference.value, Decl(strictSupertypeInjection.ts, 0, 28), Decl(strictSupertypeInjection.ts, 1, 23)) +>value : Symbol(value, Decl(strictSupertypeInjection.ts, 2, 14)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 0, 20)) +} +interface ComputedReference extends Reference { +>ComputedReference : Symbol(ComputedReference, Decl(strictSupertypeInjection.ts, 3, 1)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 4, 28)) +>Reference : Symbol(Reference, Decl(strictSupertypeInjection.ts, 0, 0)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 4, 28)) + + readonly value: Value; +>value : Symbol(ComputedReference.value, Decl(strictSupertypeInjection.ts, 4, 61)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 4, 28)) + + effect: unknown; +>effect : Symbol(ComputedReference.effect, Decl(strictSupertypeInjection.ts, 5, 26)) +} +interface InjectionConstraint {} +>InjectionConstraint : Symbol(InjectionConstraint, Decl(strictSupertypeInjection.ts, 7, 1)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 8, 30)) + +type InjectionKey = symbol & InjectionConstraint; +>InjectionKey : Symbol(InjectionKey, Decl(strictSupertypeInjection.ts, 8, 39)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 9, 18)) +>InjectionConstraint : Symbol(InjectionConstraint, Decl(strictSupertypeInjection.ts, 7, 1)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 9, 18)) + +declare function inject(key: InjectionKey | string, fallback: Value): Value; +>inject : Symbol(inject, Decl(strictSupertypeInjection.ts, 9, 63)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 11, 24)) +>key : Symbol(key, Decl(strictSupertypeInjection.ts, 11, 31)) +>InjectionKey : Symbol(InjectionKey, Decl(strictSupertypeInjection.ts, 8, 39)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 11, 24)) +>fallback : Symbol(fallback, Decl(strictSupertypeInjection.ts, 11, 65)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 11, 24)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 11, 24)) + +declare function ref(): Reference; +>ref : Symbol(ref, Decl(strictSupertypeInjection.ts, 11, 90)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 12, 21)) +>Reference : Symbol(Reference, Decl(strictSupertypeInjection.ts, 0, 0)) +>Value : Symbol(Value, Decl(strictSupertypeInjection.ts, 12, 21)) + +declare const key: InjectionKey<{ visibleIds: ComputedReference }>; +>key : Symbol(key, Decl(strictSupertypeInjection.ts, 13, 13)) +>InjectionKey : Symbol(InjectionKey, Decl(strictSupertypeInjection.ts, 8, 39)) +>visibleIds : Symbol(visibleIds, Decl(strictSupertypeInjection.ts, 13, 33)) +>ComputedReference : Symbol(ComputedReference, Decl(strictSupertypeInjection.ts, 3, 1)) + +const visibleIds = inject(key, { visibleIds: ref() }).visibleIds; +>visibleIds : Symbol(visibleIds, Decl(strictSupertypeInjection.ts, 15, 5)) +>inject(key, { visibleIds: ref() }).visibleIds : Symbol(visibleIds, Decl(strictSupertypeInjection.ts, 15, 32)) +>inject : Symbol(inject, Decl(strictSupertypeInjection.ts, 9, 63)) +>key : Symbol(key, Decl(strictSupertypeInjection.ts, 13, 13)) +>visibleIds : Symbol(visibleIds, Decl(strictSupertypeInjection.ts, 15, 32)) +>ref : Symbol(ref, Decl(strictSupertypeInjection.ts, 11, 90)) +>visibleIds : Symbol(visibleIds, Decl(strictSupertypeInjection.ts, 15, 32)) + diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.types b/tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.types new file mode 100644 index 0000000000000..af1577777c2ce --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeInjection.types @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/strictSupertypeInjection.ts] //// + +=== strictSupertypeInjection.ts === +interface Reference { + get value(): Value; +>value : Value + + set value(value: Value); +>value : Value +>value : Value +} +interface ComputedReference extends Reference { + readonly value: Value; +>value : Value + + effect: unknown; +>effect : unknown +} +interface InjectionConstraint {} +type InjectionKey = symbol & InjectionConstraint; +>InjectionKey : InjectionKey + +declare function inject(key: InjectionKey | string, fallback: Value): Value; +>inject : (key: InjectionKey | string, fallback: Value) => Value +>key : string | InjectionKey +>fallback : Value + +declare function ref(): Reference; +>ref : () => Reference + +declare const key: InjectionKey<{ visibleIds: ComputedReference }>; +>key : InjectionKey<{ visibleIds: ComputedReference; }> +>visibleIds : ComputedReference + +const visibleIds = inject(key, { visibleIds: ref() }).visibleIds; +>visibleIds : Reference +>inject(key, { visibleIds: ref() }).visibleIds : Reference +>inject(key, { visibleIds: ref() }) : { visibleIds: Reference; } +>inject : (key: InjectionKey | string, fallback: Value) => Value +>key : InjectionKey<{ visibleIds: ComputedReference; }> +>{ visibleIds: ref() } : { visibleIds: Reference; } +>visibleIds : Reference +>ref() : Reference +>ref : () => Reference +>visibleIds : Reference + diff --git a/tsc/testdata/tests/cases/compiler/strictSupertypeInjection.ts b/tsc/testdata/tests/cases/compiler/strictSupertypeInjection.ts new file mode 100644 index 0000000000000..3deb664ccac63 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/strictSupertypeInjection.ts @@ -0,0 +1,19 @@ +// @strict: true +// @noEmit: true + +interface Reference { + get value(): Value; + set value(value: Value); +} +interface ComputedReference extends Reference { + readonly value: Value; + effect: unknown; +} +interface InjectionConstraint {} +type InjectionKey = symbol & InjectionConstraint; + +declare function inject(key: InjectionKey | string, fallback: Value): Value; +declare function ref(): Reference; +declare const key: InjectionKey<{ visibleIds: ComputedReference }>; + +const visibleIds = inject(key, { visibleIds: ref() }).visibleIds; From 13b9759c168fe51ede196eed6f97524a2be0ab86 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:35:26 -0700 Subject: [PATCH 010/116] Add historical coverage: strict supertype concat Exact JS5.9 source builds and original libraries: base 479285d0ac293c35a926508d17f0bb5eca7e0303, initial b7439c1baf62f9ce18cde8ae8ec455f64b29ec15, final cb554a834ee17236acb2d34f545b14ab43b68f8e; current native a0a0ff55cab4a1f81b7123ab219c97a2f1ed703d. Diagnostic codes before=none, initial=2345, final=none, current=none. Array concatenation must infer a compatible element union when a class getter interacts with a mutable optional suggestion property; strict-only comparison leaves the first class as the inferred element type and rejects the second array. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61903#issuecomment-2988696289 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/strictSupertypeConcat.symbols | 50 +++++++++++++++++++ .../compiler/strictSupertypeConcat.types | 39 +++++++++++++++ .../cases/compiler/strictSupertypeConcat.ts | 19 +++++++ 3 files changed, 108 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.types create mode 100644 tsc/testdata/tests/cases/compiler/strictSupertypeConcat.ts diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.symbols b/tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.symbols new file mode 100644 index 0000000000000..61a3ebe1611e5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.symbols @@ -0,0 +1,50 @@ +//// [tests/cases/compiler/strictSupertypeConcat.ts] //// + +=== strictSupertypeConcat.ts === +declare class User { +>User : Symbol(User, Decl(strictSupertypeConcat.ts, 0, 0)) + + get initial(): string; +>initial : Symbol(User.initial, Decl(strictSupertypeConcat.ts, 0, 20)) +} +declare class Group { +>Group : Symbol(Group, Decl(strictSupertypeConcat.ts, 2, 1)) + + memberCount: number; +>memberCount : Symbol(Group.memberCount, Decl(strictSupertypeConcat.ts, 3, 21)) +} +interface Suggestion { +>Suggestion : Symbol(Suggestion, Decl(strictSupertypeConcat.ts, 5, 1)) + + initial?: string; +>initial : Symbol(Suggestion.initial, Decl(strictSupertypeConcat.ts, 6, 22)) +} +type Many = Value | readonly Value[]; +>Many : Symbol(Many, Decl(strictSupertypeConcat.ts, 8, 1)) +>Value : Symbol(Value, Decl(strictSupertypeConcat.ts, 9, 10)) +>Value : Symbol(Value, Decl(strictSupertypeConcat.ts, 9, 10)) +>Value : Symbol(Value, Decl(strictSupertypeConcat.ts, 9, 10)) + +declare function concat(...values: Many[]): Value[]; +>concat : Symbol(concat, Decl(strictSupertypeConcat.ts, 9, 44)) +>Value : Symbol(Value, Decl(strictSupertypeConcat.ts, 11, 24)) +>values : Symbol(values, Decl(strictSupertypeConcat.ts, 11, 31)) +>Many : Symbol(Many, Decl(strictSupertypeConcat.ts, 8, 1)) +>Value : Symbol(Value, Decl(strictSupertypeConcat.ts, 11, 24)) +>Value : Symbol(Value, Decl(strictSupertypeConcat.ts, 11, 24)) + +declare const pending: User[]; +>pending : Symbol(pending, Decl(strictSupertypeConcat.ts, 12, 13)) +>User : Symbol(User, Decl(strictSupertypeConcat.ts, 0, 0)) + +declare const suggestions: (Group | Suggestion)[]; +>suggestions : Symbol(suggestions, Decl(strictSupertypeConcat.ts, 13, 13)) +>Group : Symbol(Group, Decl(strictSupertypeConcat.ts, 2, 1)) +>Suggestion : Symbol(Suggestion, Decl(strictSupertypeConcat.ts, 5, 1)) + +const items = concat(pending, suggestions); +>items : Symbol(items, Decl(strictSupertypeConcat.ts, 15, 5)) +>concat : Symbol(concat, Decl(strictSupertypeConcat.ts, 9, 44)) +>pending : Symbol(pending, Decl(strictSupertypeConcat.ts, 12, 13)) +>suggestions : Symbol(suggestions, Decl(strictSupertypeConcat.ts, 13, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.types b/tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.types new file mode 100644 index 0000000000000..30d51285c46cc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/strictSupertypeConcat.types @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/strictSupertypeConcat.ts] //// + +=== strictSupertypeConcat.ts === +declare class User { +>User : User + + get initial(): string; +>initial : string +} +declare class Group { +>Group : Group + + memberCount: number; +>memberCount : number +} +interface Suggestion { + initial?: string; +>initial : string | undefined +} +type Many = Value | readonly Value[]; +>Many : Many + +declare function concat(...values: Many[]): Value[]; +>concat : (...values: Many[]) => Value[] +>values : Many[] + +declare const pending: User[]; +>pending : User[] + +declare const suggestions: (Group | Suggestion)[]; +>suggestions : (Group | Suggestion)[] + +const items = concat(pending, suggestions); +>items : (Group | Suggestion)[] +>concat(pending, suggestions) : (Group | Suggestion)[] +>concat : (...values: Many[]) => Value[] +>pending : User[] +>suggestions : (Group | Suggestion)[] + diff --git a/tsc/testdata/tests/cases/compiler/strictSupertypeConcat.ts b/tsc/testdata/tests/cases/compiler/strictSupertypeConcat.ts new file mode 100644 index 0000000000000..80a46ae869877 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/strictSupertypeConcat.ts @@ -0,0 +1,19 @@ +// @strict: true +// @noEmit: true + +declare class User { + get initial(): string; +} +declare class Group { + memberCount: number; +} +interface Suggestion { + initial?: string; +} +type Many = Value | readonly Value[]; + +declare function concat(...values: Many[]): Value[]; +declare const pending: User[]; +declare const suggestions: (Group | Suggestion)[]; + +const items = concat(pending, suggestions); From 8340b83a152ce29c5eb447dfaa7af991edf4e696 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:46:50 -0700 Subject: [PATCH 011/116] Add historical coverage: message port handler event types Fixed JS6.0.3 checker, exact historical DOM or WebWorker declarations, unchanged ES5 library, isolated library diagnostics. Before 700ee076 clean; initial 9fda4c0 has two TS2339 on event.data; restoring MessageEvent in 3de67a4 and final 9419e23 are clean. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60987#issuecomment-2597220680 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../messagePortHandlerEventTypes.symbols | 32 +++++++++++++++++ .../messagePortHandlerEventTypes.types | 35 +++++++++++++++++++ .../compiler/messagePortHandlerEventTypes.ts | 11 ++++++ 3 files changed, 78 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.types create mode 100644 tsc/testdata/tests/cases/compiler/messagePortHandlerEventTypes.ts diff --git a/tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.symbols b/tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.symbols new file mode 100644 index 0000000000000..c234f2b4eaa95 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/messagePortHandlerEventTypes.ts] //// + +=== messagePortHandlerEventTypes.ts === +declare const port: MessagePort; +>port : Symbol(port, Decl(messagePortHandlerEventTypes.ts, 0, 13)) +>MessagePort : Symbol(MessagePort, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +port.onmessage = event => { +>port.onmessage : Symbol(MessageEventTarget.onmessage, Decl(lib.dom.d.ts, --, --)) +>port : Symbol(port, Decl(messagePortHandlerEventTypes.ts, 0, 13)) +>onmessage : Symbol(MessageEventTarget.onmessage, Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(messagePortHandlerEventTypes.ts, 1, 16)) + + event.data; +>event.data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(messagePortHandlerEventTypes.ts, 1, 16)) +>data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) + +}; +port.onmessageerror = event => { +>port.onmessageerror : Symbol(MessageEventTarget.onmessageerror, Decl(lib.dom.d.ts, --, --)) +>port : Symbol(port, Decl(messagePortHandlerEventTypes.ts, 0, 13)) +>onmessageerror : Symbol(MessageEventTarget.onmessageerror, Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(messagePortHandlerEventTypes.ts, 4, 21)) + + event.data; +>event.data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(messagePortHandlerEventTypes.ts, 4, 21)) +>data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) + +}; + diff --git a/tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.types b/tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.types new file mode 100644 index 0000000000000..e9d12ca08cab1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/messagePortHandlerEventTypes.types @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/messagePortHandlerEventTypes.ts] //// + +=== messagePortHandlerEventTypes.ts === +declare const port: MessagePort; +>port : MessagePort + +port.onmessage = event => { +>port.onmessage = event => { event.data;} : (this: MessagePort, event: MessageEvent) => void +>port.onmessage : ((this: MessagePort, ev: MessageEvent) => any) | null +>port : MessagePort +>onmessage : ((this: MessagePort, ev: MessageEvent) => any) | null +>event => { event.data;} : (this: MessagePort, event: MessageEvent) => void +>event : MessageEvent + + event.data; +>event.data : any +>event : MessageEvent +>data : any + +}; +port.onmessageerror = event => { +>port.onmessageerror = event => { event.data;} : (this: MessagePort, event: MessageEvent) => void +>port.onmessageerror : ((this: MessagePort, ev: MessageEvent) => any) | null +>port : MessagePort +>onmessageerror : ((this: MessagePort, ev: MessageEvent) => any) | null +>event => { event.data;} : (this: MessagePort, event: MessageEvent) => void +>event : MessageEvent + + event.data; +>event.data : any +>event : MessageEvent +>data : any + +}; + diff --git a/tsc/testdata/tests/cases/compiler/messagePortHandlerEventTypes.ts b/tsc/testdata/tests/cases/compiler/messagePortHandlerEventTypes.ts new file mode 100644 index 0000000000000..f2c829805f29b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/messagePortHandlerEventTypes.ts @@ -0,0 +1,11 @@ +// @strict: true +// @lib: es5,dom +// @noEmit: true + +declare const port: MessagePort; +port.onmessage = event => { + event.data; +}; +port.onmessageerror = event => { + event.data; +}; From 09e9de34195cd41fbfbb75e4ab429d97efc32881 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:46:54 -0700 Subject: [PATCH 012/116] Add historical coverage: worker implementation handler this Fixed JS6.0.3 checker, exact historical DOM or WebWorker declarations, unchanged ES5 library, isolated library diagnostics. Before 700ee076 clean; initial 9fda4c0 and event-type-only fix 3de67a4 retain two TS2416 this-parameter incompatibilities; d08731b and final 9419e23 are clean. Repeated in https://redirect.github.com/microsoft/TypeScript/pull/61073#issuecomment-2622517327: base0652664 clean, initiald3fbb1a and attempted event-map restore1a3d836 fail identically, finalb2de5f0 clean. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60987#issuecomment-2597220680 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../workerImplementationHandlerThis.symbols | 35 +++++++++++++++++++ .../workerImplementationHandlerThis.types | 27 ++++++++++++++ .../workerImplementationHandlerThis.ts | 11 ++++++ 3 files changed, 73 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.types create mode 100644 tsc/testdata/tests/cases/compiler/workerImplementationHandlerThis.ts diff --git a/tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.symbols b/tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.symbols new file mode 100644 index 0000000000000..09e0e6137bca2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.symbols @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/workerImplementationHandlerThis.ts] //// + +=== workerImplementationHandlerThis.ts === +declare class WorkerReplacement extends EventTarget implements Worker { +>WorkerReplacement : Symbol(WorkerReplacement, Decl(workerImplementationHandlerThis.ts, 0, 0)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + onmessage: ((this: Worker, event: MessageEvent) => any) | null; +>onmessage : Symbol(WorkerReplacement.onmessage, Decl(workerImplementationHandlerThis.ts, 0, 71)) +>this : Symbol(this, Decl(workerImplementationHandlerThis.ts, 1, 17)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(workerImplementationHandlerThis.ts, 1, 30)) +>MessageEvent : Symbol(MessageEvent, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + onmessageerror: ((this: Worker, event: MessageEvent) => any) | null; +>onmessageerror : Symbol(WorkerReplacement.onmessageerror, Decl(workerImplementationHandlerThis.ts, 1, 67)) +>this : Symbol(this, Decl(workerImplementationHandlerThis.ts, 2, 22)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(workerImplementationHandlerThis.ts, 2, 35)) +>MessageEvent : Symbol(MessageEvent, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + onerror: Worker["onerror"]; +>onerror : Symbol(WorkerReplacement.onerror, Decl(workerImplementationHandlerThis.ts, 2, 72)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + postMessage: Worker["postMessage"]; +>postMessage : Symbol(WorkerReplacement.postMessage, Decl(workerImplementationHandlerThis.ts, 3, 31)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + terminate: Worker["terminate"]; +>terminate : Symbol(WorkerReplacement.terminate, Decl(workerImplementationHandlerThis.ts, 4, 39)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.types b/tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.types new file mode 100644 index 0000000000000..31e8060b820f6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/workerImplementationHandlerThis.types @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/workerImplementationHandlerThis.ts] //// + +=== workerImplementationHandlerThis.ts === +declare class WorkerReplacement extends EventTarget implements Worker { +>WorkerReplacement : WorkerReplacement +>EventTarget : EventTarget + + onmessage: ((this: Worker, event: MessageEvent) => any) | null; +>onmessage : ((this: Worker, event: MessageEvent) => any) | null +>this : Worker +>event : MessageEvent + + onmessageerror: ((this: Worker, event: MessageEvent) => any) | null; +>onmessageerror : ((this: Worker, event: MessageEvent) => any) | null +>this : Worker +>event : MessageEvent + + onerror: Worker["onerror"]; +>onerror : ((this: AbstractWorker, ev: ErrorEvent) => any) | null + + postMessage: Worker["postMessage"]; +>postMessage : { (message: any, transfer: Transferable[]): void; (message: any, options?: StructuredSerializeOptions): void; } + + terminate: Worker["terminate"]; +>terminate : () => void +} + diff --git a/tsc/testdata/tests/cases/compiler/workerImplementationHandlerThis.ts b/tsc/testdata/tests/cases/compiler/workerImplementationHandlerThis.ts new file mode 100644 index 0000000000000..c02fe694ef209 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/workerImplementationHandlerThis.ts @@ -0,0 +1,11 @@ +// @strict: true +// @lib: es5,dom +// @noEmit: true + +declare class WorkerReplacement extends EventTarget implements Worker { + onmessage: ((this: Worker, event: MessageEvent) => any) | null; + onmessageerror: ((this: Worker, event: MessageEvent) => any) | null; + onerror: Worker["onerror"]; + postMessage: Worker["postMessage"]; + terminate: Worker["terminate"]; +} From ae3504fd61e0bf89112cabecc1d5a656089d23e1 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:46:57 -0700 Subject: [PATCH 013/116] Add historical coverage: worker global message handler this Fixed JS6.0.3 checker, exact historical DOM or WebWorker declarations, unchanged ES5 library, isolated library diagnostics. Before 700ee076 clean; initial 9fda4c0 and event-type-only fix 3de67a4 produce source-matching TS2345 receiver assignment and TS2684 optional handler invocation; d08731b and final 9419e23 are clean. Repeated in https://redirect.github.com/microsoft/TypeScript/pull/61073#issuecomment-2622517327: base0652664 clean, initiald3fbb1a and attempted event-map restore1a3d836 fail identically, finalb2de5f0 clean. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60987#issuecomment-2597220680 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../workerGlobalMessageHandlerThis.symbols | 24 +++++++++++++++++++ .../workerGlobalMessageHandlerThis.types | 22 +++++++++++++++++ .../workerGlobalMessageHandlerThis.ts | 9 +++++++ 3 files changed, 55 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.types create mode 100644 tsc/testdata/tests/cases/compiler/workerGlobalMessageHandlerThis.ts diff --git a/tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.symbols b/tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.symbols new file mode 100644 index 0000000000000..f2da0ea9d50b9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.symbols @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/workerGlobalMessageHandlerThis.ts] //// + +=== workerGlobalMessageHandlerThis.ts === +declare function createMessageReader(port: MessagePort | Worker | DedicatedWorkerGlobalScope): void; +>createMessageReader : Symbol(createMessageReader, Decl(workerGlobalMessageHandlerThis.ts, 0, 0)) +>port : Symbol(port, Decl(workerGlobalMessageHandlerThis.ts, 0, 37)) +>MessagePort : Symbol(MessagePort, Decl(lib.webworker.d.ts, --, --), Decl(lib.webworker.d.ts, --, --)) +>Worker : Symbol(Worker, Decl(lib.webworker.d.ts, --, --), Decl(lib.webworker.d.ts, --, --)) +>DedicatedWorkerGlobalScope : Symbol(DedicatedWorkerGlobalScope, Decl(lib.webworker.d.ts, --, --), Decl(lib.webworker.d.ts, --, --)) + +createMessageReader(self); +>createMessageReader : Symbol(createMessageReader, Decl(workerGlobalMessageHandlerThis.ts, 0, 0)) +>self : Symbol(self, Decl(lib.webworker.d.ts, --, --)) + +declare const event: MessageEvent; +>event : Symbol(event, Decl(workerGlobalMessageHandlerThis.ts, 3, 13)) +>MessageEvent : Symbol(MessageEvent, Decl(lib.webworker.d.ts, --, --), Decl(lib.webworker.d.ts, --, --), Decl(lib.webworker.d.ts, --, --)) + +self.onmessage?.(event); +>self.onmessage : Symbol(onmessage, Decl(lib.webworker.d.ts, --, --)) +>self : Symbol(self, Decl(lib.webworker.d.ts, --, --)) +>onmessage : Symbol(onmessage, Decl(lib.webworker.d.ts, --, --)) +>event : Symbol(event, Decl(workerGlobalMessageHandlerThis.ts, 3, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.types b/tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.types new file mode 100644 index 0000000000000..e6f994117bc20 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/workerGlobalMessageHandlerThis.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/workerGlobalMessageHandlerThis.ts] //// + +=== workerGlobalMessageHandlerThis.ts === +declare function createMessageReader(port: MessagePort | Worker | DedicatedWorkerGlobalScope): void; +>createMessageReader : (port: MessagePort | Worker | DedicatedWorkerGlobalScope) => void +>port : DedicatedWorkerGlobalScope | MessagePort | Worker + +createMessageReader(self); +>createMessageReader(self) : void +>createMessageReader : (port: MessagePort | Worker | DedicatedWorkerGlobalScope) => void +>self : WorkerGlobalScope & typeof globalThis + +declare const event: MessageEvent; +>event : MessageEvent + +self.onmessage?.(event); +>self.onmessage?.(event) : any +>self.onmessage : ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null +>self : WorkerGlobalScope & typeof globalThis +>onmessage : ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null +>event : MessageEvent + diff --git a/tsc/testdata/tests/cases/compiler/workerGlobalMessageHandlerThis.ts b/tsc/testdata/tests/cases/compiler/workerGlobalMessageHandlerThis.ts new file mode 100644 index 0000000000000..71f86148118c4 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/workerGlobalMessageHandlerThis.ts @@ -0,0 +1,9 @@ +// @strict: true +// @lib: es5,webworker +// @noEmit: true + +declare function createMessageReader(port: MessagePort | Worker | DedicatedWorkerGlobalScope): void; +createMessageReader(self); + +declare const event: MessageEvent; +self.onmessage?.(event); From 2ac90430ca4d3474e7eaacdafc1a19f198a0898b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:53:52 -0700 Subject: [PATCH 014/116] Add historical coverage: worker subtype handler this Fixed JS6.0.3 checker with exact historical DOM: before700ee076, initial9fda4c0 and eventfix3de67a4 clean; polymorphic-this intermediate d08731b produces source-matching TS2345 rejecting a Worker subtype with an extra messages field; generic receiver fix b858667 and final9419e23 clean. Removed Partytown's intermediate postMessage override without losing the actual inherited-onmessage receiver failure. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60987#issuecomment-2605554718 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/workerSubtypeHandlerThis.symbols | 24 +++++++++++++++++++ .../compiler/workerSubtypeHandlerThis.types | 20 ++++++++++++++++ .../compiler/workerSubtypeHandlerThis.ts | 11 +++++++++ 3 files changed, 55 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.types create mode 100644 tsc/testdata/tests/cases/compiler/workerSubtypeHandlerThis.ts diff --git a/tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.symbols b/tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.symbols new file mode 100644 index 0000000000000..b4b00ab36925c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.symbols @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/workerSubtypeHandlerThis.ts] //// + +=== workerSubtypeHandlerThis.ts === +interface MockWorker extends Worker { +>MockWorker : Symbol(MockWorker, Decl(workerSubtypeHandlerThis.ts, 0, 0)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + messages: unknown[]; +>messages : Symbol(MockWorker.messages, Decl(workerSubtypeHandlerThis.ts, 0, 37)) +} + +declare function forward(worker: Worker): void; +>forward : Symbol(forward, Decl(workerSubtypeHandlerThis.ts, 2, 1)) +>worker : Symbol(worker, Decl(workerSubtypeHandlerThis.ts, 4, 25)) +>Worker : Symbol(Worker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +declare const worker: MockWorker; +>worker : Symbol(worker, Decl(workerSubtypeHandlerThis.ts, 5, 13)) +>MockWorker : Symbol(MockWorker, Decl(workerSubtypeHandlerThis.ts, 0, 0)) + +forward(worker); +>forward : Symbol(forward, Decl(workerSubtypeHandlerThis.ts, 2, 1)) +>worker : Symbol(worker, Decl(workerSubtypeHandlerThis.ts, 5, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.types b/tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.types new file mode 100644 index 0000000000000..3846cb5022d02 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/workerSubtypeHandlerThis.types @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/workerSubtypeHandlerThis.ts] //// + +=== workerSubtypeHandlerThis.ts === +interface MockWorker extends Worker { + messages: unknown[]; +>messages : unknown[] +} + +declare function forward(worker: Worker): void; +>forward : (worker: Worker) => void +>worker : Worker + +declare const worker: MockWorker; +>worker : MockWorker + +forward(worker); +>forward(worker) : void +>forward : (worker: Worker) => void +>worker : MockWorker + diff --git a/tsc/testdata/tests/cases/compiler/workerSubtypeHandlerThis.ts b/tsc/testdata/tests/cases/compiler/workerSubtypeHandlerThis.ts new file mode 100644 index 0000000000000..0027eeb358b82 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/workerSubtypeHandlerThis.ts @@ -0,0 +1,11 @@ +// @strict: true +// @lib: es5,dom +// @noEmit: true + +interface MockWorker extends Worker { + messages: unknown[]; +} + +declare function forward(worker: Worker): void; +declare const worker: MockWorker; +forward(worker); From f7974738dbebd66bad6aa9e31639d36f0c2e2bee Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 12:53:56 -0700 Subject: [PATCH 015/116] Add historical coverage: deferred rule message inference Exact JS5.9 source checkers and original libraries: base8c62e084 clean, report-era0ca87b3c TS2322 from nested callback messageId widening to string, finaldefd3535 clean; current nativea0a0ff55 clean. Removing the source's legacy [T][T extends unknown ? 0 : never] inference blocker eliminates the historical regression. Three related existing generic-call tests stay clean on the report-era checker. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61668#issuecomment-2860922921 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../contextualRuleMessageInference.symbols | 42 +++++++++++++++++ .../contextualRuleMessageInference.types | 47 +++++++++++++++++++ .../contextualRuleMessageInference.ts | 15 ++++++ 3 files changed, 104 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.types create mode 100644 tsc/testdata/tests/cases/compiler/contextualRuleMessageInference.ts diff --git a/tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.symbols b/tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.symbols new file mode 100644 index 0000000000000..79cd1036db42e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.symbols @@ -0,0 +1,42 @@ +//// [tests/cases/compiler/contextualRuleMessageInference.ts] //// + +=== contextualRuleMessageInference.ts === +type DeferredInference = [T][T extends unknown ? 0 : never]; +>DeferredInference : Symbol(DeferredInference, Decl(contextualRuleMessageInference.ts, 0, 0)) +>T : Symbol(T, Decl(contextualRuleMessageInference.ts, 0, 23)) +>T : Symbol(T, Decl(contextualRuleMessageInference.ts, 0, 23)) +>T : Symbol(T, Decl(contextualRuleMessageInference.ts, 0, 23)) + +declare function runRule( +>runRule : Symbol(runRule, Decl(contextualRuleMessageInference.ts, 0, 63)) +>Message : Symbol(Message, Decl(contextualRuleMessageInference.ts, 2, 25)) + + rule: Message, +>rule : Symbol(rule, Decl(contextualRuleMessageInference.ts, 2, 49)) +>Message : Symbol(Message, Decl(contextualRuleMessageInference.ts, 2, 25)) + + tests: { invalid: readonly { errors: readonly { messageId: DeferredInference }[] }[] }, +>tests : Symbol(tests, Decl(contextualRuleMessageInference.ts, 3, 18)) +>invalid : Symbol(invalid, Decl(contextualRuleMessageInference.ts, 4, 12)) +>errors : Symbol(errors, Decl(contextualRuleMessageInference.ts, 4, 32)) +>messageId : Symbol(messageId, Decl(contextualRuleMessageInference.ts, 4, 51)) +>DeferredInference : Symbol(DeferredInference, Decl(contextualRuleMessageInference.ts, 0, 0)) +>Message : Symbol(Message, Decl(contextualRuleMessageInference.ts, 2, 25)) + +): void; + +runRule("forbiddenAct", { +>runRule : Symbol(runRule, Decl(contextualRuleMessageInference.ts, 0, 63)) + + invalid: ["act()"].map(() => ({ +>invalid : Symbol(invalid, Decl(contextualRuleMessageInference.ts, 7, 25)) +>["act()"].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) + + errors: [{ messageId: "forbiddenAct" }], +>errors : Symbol(errors, Decl(contextualRuleMessageInference.ts, 8, 35)) +>messageId : Symbol(messageId, Decl(contextualRuleMessageInference.ts, 9, 18)) + + })), +}); + diff --git a/tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.types b/tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.types new file mode 100644 index 0000000000000..18b64bcc540d4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualRuleMessageInference.types @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/contextualRuleMessageInference.ts] //// + +=== contextualRuleMessageInference.ts === +type DeferredInference = [T][T extends unknown ? 0 : never]; +>DeferredInference : DeferredInference + +declare function runRule( +>runRule : (rule: Message, tests: { invalid: readonly { errors: readonly { messageId: DeferredInference; }[]; }[]; }) => void + + rule: Message, +>rule : Message + + tests: { invalid: readonly { errors: readonly { messageId: DeferredInference }[] }[] }, +>tests : { invalid: readonly { errors: readonly { messageId: DeferredInference; }[]; }[]; } +>invalid : readonly { errors: readonly { messageId: DeferredInference; }[]; }[] +>errors : readonly { messageId: DeferredInference; }[] +>messageId : DeferredInference + +): void; + +runRule("forbiddenAct", { +>runRule("forbiddenAct", { invalid: ["act()"].map(() => ({ errors: [{ messageId: "forbiddenAct" }], })),}) : void +>runRule : (rule: Message, tests: { invalid: readonly { errors: readonly { messageId: DeferredInference; }[]; }[]; }) => void +>"forbiddenAct" : "forbiddenAct" +>{ invalid: ["act()"].map(() => ({ errors: [{ messageId: "forbiddenAct" }], })),} : { invalid: { errors: { messageId: "forbiddenAct"; }[]; }[]; } + + invalid: ["act()"].map(() => ({ +>invalid : { errors: { messageId: "forbiddenAct"; }[]; }[] +>["act()"].map(() => ({ errors: [{ messageId: "forbiddenAct" }], })) : { errors: { messageId: "forbiddenAct"; }[]; }[] +>["act()"].map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>["act()"] : string[] +>"act()" : "act()" +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>() => ({ errors: [{ messageId: "forbiddenAct" }], }) : () => { errors: { messageId: "forbiddenAct"; }[]; } +>({ errors: [{ messageId: "forbiddenAct" }], }) : { errors: { messageId: "forbiddenAct"; }[]; } +>{ errors: [{ messageId: "forbiddenAct" }], } : { errors: { messageId: "forbiddenAct"; }[]; } + + errors: [{ messageId: "forbiddenAct" }], +>errors : { messageId: "forbiddenAct"; }[] +>[{ messageId: "forbiddenAct" }] : { messageId: "forbiddenAct"; }[] +>{ messageId: "forbiddenAct" } : { messageId: "forbiddenAct"; } +>messageId : "forbiddenAct" +>"forbiddenAct" : "forbiddenAct" + + })), +}); + diff --git a/tsc/testdata/tests/cases/compiler/contextualRuleMessageInference.ts b/tsc/testdata/tests/cases/compiler/contextualRuleMessageInference.ts new file mode 100644 index 0000000000000..9da85c3e0d57b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualRuleMessageInference.ts @@ -0,0 +1,15 @@ +// @strict: true +// @noEmit: true + +type DeferredInference = [T][T extends unknown ? 0 : never]; + +declare function runRule( + rule: Message, + tests: { invalid: readonly { errors: readonly { messageId: DeferredInference }[] }[] }, +): void; + +runRule("forbiddenAct", { + invalid: ["act()"].map(() => ({ + errors: [{ messageId: "forbiddenAct" }], + })), +}); From 168d455bfd1c454093b5f4707d79cb612e2fa76b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:12:25 -0700 Subject: [PATCH 016/116] Add historical coverage: callback assigned non null auto type Exact original PR source checkers: base b3c67d32020a3015fe068fbcb1dcfb18aedcaad3 clean; head 46cd4219ddbf243c34088bc0682f7f1da5a4b261 produces source-matching TS7034 and TS7005 for an unannotated variable assigned inside a callback and read under non-null assertion. Existing nonNullFullInference stays diagnostic-clean before/after under original and strict options. These are original PR snapshots, not the later bot merge build, which is no longer available. Current pinned native compiler is clean. The diagnostic improvement was never merged; this test records currently accepted exact user-code form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60523#issuecomment-3021418850 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/callbackAssignedNonNull.symbols | 27 ++++++++++++++++ .../compiler/callbackAssignedNonNull.types | 32 +++++++++++++++++++ .../cases/compiler/callbackAssignedNonNull.ts | 12 +++++++ 3 files changed, 71 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.types create mode 100644 tsc/testdata/tests/cases/compiler/callbackAssignedNonNull.ts diff --git a/tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.symbols b/tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.symbols new file mode 100644 index 0000000000000..b517ff4b9f51e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/callbackAssignedNonNull.ts] //// + +=== callbackAssignedNonNull.ts === +declare function initialize(callback: (cancel: () => void) => void): void; +>initialize : Symbol(initialize, Decl(callbackAssignedNonNull.ts, 0, 0)) +>callback : Symbol(callback, Decl(callbackAssignedNonNull.ts, 0, 28)) +>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 0, 39)) + +function start() { +>start : Symbol(start, Decl(callbackAssignedNonNull.ts, 0, 74)) + + let cancel; +>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 3, 7)) + + initialize(value => { +>initialize : Symbol(initialize, Decl(callbackAssignedNonNull.ts, 0, 0)) +>value : Symbol(value, Decl(callbackAssignedNonNull.ts, 4, 15)) + + cancel = value; +>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 3, 7)) +>value : Symbol(value, Decl(callbackAssignedNonNull.ts, 4, 15)) + + }); + cancel!(); +>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 3, 7)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.types b/tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.types new file mode 100644 index 0000000000000..bc37613da44da --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callbackAssignedNonNull.types @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/callbackAssignedNonNull.ts] //// + +=== callbackAssignedNonNull.ts === +declare function initialize(callback: (cancel: () => void) => void): void; +>initialize : (callback: (cancel: () => void) => void) => void +>callback : (cancel: () => void) => void +>cancel : () => void + +function start() { +>start : () => void + + let cancel; +>cancel : any + + initialize(value => { +>initialize(value => { cancel = value; }) : void +>initialize : (callback: (cancel: () => void) => void) => void +>value => { cancel = value; } : (value: () => void) => void +>value : () => void + + cancel = value; +>cancel = value : () => void +>cancel : any +>value : () => void + + }); + cancel!(); +>cancel!() : any +>cancel! : any +>cancel : any +} + diff --git a/tsc/testdata/tests/cases/compiler/callbackAssignedNonNull.ts b/tsc/testdata/tests/cases/compiler/callbackAssignedNonNull.ts new file mode 100644 index 0000000000000..b5c5b640c222e --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/callbackAssignedNonNull.ts @@ -0,0 +1,12 @@ +// @strict: true +// @noEmit: true + +declare function initialize(callback: (cancel: () => void) => void): void; + +function start() { + let cancel; + initialize(value => { + cancel = value; + }); + cancel!(); +} From d90d31dc0ac701a41a482e066f811e28608d9e3e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:16:09 -0700 Subject: [PATCH 017/116] Add historical coverage: callable weak metadata intersection Exact ORIGINAL PR source checkers and matching historical libraries: base56a08250f3516b3f5bc120d6c7ab4450a9a69352 clean; head0b454af177071402294f1baa8ca6d8024ce7cdd4 TS2559 rejecting a callable intersection with optional metadata; current pinned native clean. Existing weakType, intersectionAsWeakTypeSource and weakTypeAndPrimitiveNarrowing diagnostic sets are unchanged. These original December2024 snapshots are NOT the unrecovered July2025 bot merge/main builds; primitive LiteralUnion and indexed Query controls stay clean and are NOT classified by this evidence. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021425964 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/callableWeakMetadata.symbols | 15 +++++++++++++++ .../compiler/callableWeakMetadata.types | 17 +++++++++++++++++ .../cases/compiler/callableWeakMetadata.ts | 8 ++++++++ 3 files changed, 40 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/callableWeakMetadata.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/callableWeakMetadata.types create mode 100644 tsc/testdata/tests/cases/compiler/callableWeakMetadata.ts diff --git a/tsc/testdata/baselines/reference/compiler/callableWeakMetadata.symbols b/tsc/testdata/baselines/reference/compiler/callableWeakMetadata.symbols new file mode 100644 index 0000000000000..676de7eccdd88 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callableWeakMetadata.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/callableWeakMetadata.ts] //// + +=== callableWeakMetadata.ts === +type Initializer = (() => number) & { mutators?: [] }; +>Initializer : Symbol(Initializer, Decl(callableWeakMetadata.ts, 0, 0)) +>mutators : Symbol(mutators, Decl(callableWeakMetadata.ts, 0, 37)) + +declare function createStore(initializer: Initializer): void; +>createStore : Symbol(createStore, Decl(callableWeakMetadata.ts, 0, 54)) +>initializer : Symbol(initializer, Decl(callableWeakMetadata.ts, 2, 29)) +>Initializer : Symbol(Initializer, Decl(callableWeakMetadata.ts, 0, 0)) + +createStore(() => 1); +>createStore : Symbol(createStore, Decl(callableWeakMetadata.ts, 0, 54)) + diff --git a/tsc/testdata/baselines/reference/compiler/callableWeakMetadata.types b/tsc/testdata/baselines/reference/compiler/callableWeakMetadata.types new file mode 100644 index 0000000000000..39c2bc5701b3a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callableWeakMetadata.types @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/callableWeakMetadata.ts] //// + +=== callableWeakMetadata.ts === +type Initializer = (() => number) & { mutators?: [] }; +>Initializer : Initializer +>mutators : [] | undefined + +declare function createStore(initializer: Initializer): void; +>createStore : (initializer: Initializer) => void +>initializer : Initializer + +createStore(() => 1); +>createStore(() => 1) : void +>createStore : (initializer: Initializer) => void +>() => 1 : () => number +>1 : 1 + diff --git a/tsc/testdata/tests/cases/compiler/callableWeakMetadata.ts b/tsc/testdata/tests/cases/compiler/callableWeakMetadata.ts new file mode 100644 index 0000000000000..3fc8ba4aaeabd --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/callableWeakMetadata.ts @@ -0,0 +1,8 @@ +// @strict: true +// @noEmit: true + +type Initializer = (() => number) & { mutators?: [] }; + +declare function createStore(initializer: Initializer): void; + +createStore(() => 1); From cc322c989160e6577770b0e34b69fe6ceb3047bd Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:41:38 -0700 Subject: [PATCH 018/116] Add historical coverage: callable weak metadata call suggestion Exact original PR before56a08250 clean/head0b454af TS2560 with call suggestion; independently executed reconstructed report-adjacent main3ba257ff clean/main plus exact PR checker patch TS2560; current native clean. Zustand combine's Object.assign on its callback result has actual any return, preserved in declared callback return rather than masking the assignment with an any cast. The original 2559 case returns number and does not exercise this separate diagnostic suggestion path. Reconstructed builds are not recovered bot artifacts. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021425964 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...callableWeakMetadataCallSuggestion.symbols | 19 +++++++++++++++++++ .../callableWeakMetadataCallSuggestion.types | 19 +++++++++++++++++++ .../callableWeakMetadataCallSuggestion.ts | 9 +++++++++ 3 files changed, 47 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.types create mode 100644 tsc/testdata/tests/cases/compiler/callableWeakMetadataCallSuggestion.ts diff --git a/tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.symbols b/tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.symbols new file mode 100644 index 0000000000000..4c2aabe563a7a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/callableWeakMetadataCallSuggestion.ts] //// + +=== callableWeakMetadataCallSuggestion.ts === +type Initializer = (() => number) & { mutators?: [] }; +>Initializer : Symbol(Initializer, Decl(callableWeakMetadataCallSuggestion.ts, 0, 0)) +>mutators : Symbol(mutators, Decl(callableWeakMetadataCallSuggestion.ts, 0, 37)) + +declare function createStore(initializer: Initializer): void; +>createStore : Symbol(createStore, Decl(callableWeakMetadataCallSuggestion.ts, 0, 54)) +>initializer : Symbol(initializer, Decl(callableWeakMetadataCallSuggestion.ts, 2, 29)) +>Initializer : Symbol(Initializer, Decl(callableWeakMetadataCallSuggestion.ts, 0, 0)) + +declare const initializer: () => any; +>initializer : Symbol(initializer, Decl(callableWeakMetadataCallSuggestion.ts, 3, 13)) + +createStore(initializer); +>createStore : Symbol(createStore, Decl(callableWeakMetadataCallSuggestion.ts, 0, 54)) +>initializer : Symbol(initializer, Decl(callableWeakMetadataCallSuggestion.ts, 3, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.types b/tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.types new file mode 100644 index 0000000000000..778f805bd956f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callableWeakMetadataCallSuggestion.types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/callableWeakMetadataCallSuggestion.ts] //// + +=== callableWeakMetadataCallSuggestion.ts === +type Initializer = (() => number) & { mutators?: [] }; +>Initializer : Initializer +>mutators : [] | undefined + +declare function createStore(initializer: Initializer): void; +>createStore : (initializer: Initializer) => void +>initializer : Initializer + +declare const initializer: () => any; +>initializer : () => any + +createStore(initializer); +>createStore(initializer) : void +>createStore : (initializer: Initializer) => void +>initializer : () => any + diff --git a/tsc/testdata/tests/cases/compiler/callableWeakMetadataCallSuggestion.ts b/tsc/testdata/tests/cases/compiler/callableWeakMetadataCallSuggestion.ts new file mode 100644 index 0000000000000..23ad2e996c278 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/callableWeakMetadataCallSuggestion.ts @@ -0,0 +1,9 @@ +// @strict: true +// @noEmit: true + +type Initializer = (() => number) & { mutators?: [] }; + +declare function createStore(initializer: Initializer): void; +declare const initializer: () => any; + +createStore(initializer); From cab72bffa61a938f23b0f01decd10e3bf18168b1 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:41:42 -0700 Subject: [PATCH 019/116] Add historical coverage: empty mapped parser metadata Exact original PR base56a08250 clean/head0b454af two TS2322; reconstructed report-adjacent main3ba257ff clean plus exact checker patch two TS2322; current native clean. Published source declarations and pinned Mitosis lock demonstrate LiteralUnion uses Pick intersected with an optional marker, not a primitive string intersection. Existing mappedTypeErrors and conditionalTypesSimplifyWhenTrivial diagnostics stay unchanged. No external Prettier imports/declaration bundles included. Reconstruction is not a recovered bot artifact. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021425964 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../emptyMappedParserMetadata.symbols | 20 +++++++++++++++++++ .../compiler/emptyMappedParserMetadata.types | 18 +++++++++++++++++ .../compiler/emptyMappedParserMetadata.ts | 8 ++++++++ 3 files changed, 46 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.types create mode 100644 tsc/testdata/tests/cases/compiler/emptyMappedParserMetadata.ts diff --git a/tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.symbols b/tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.symbols new file mode 100644 index 0000000000000..62fa4442973b1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/emptyMappedParserMetadata.ts] //// + +=== emptyMappedParserMetadata.ts === +type ParserName = "babel" | (Pick & { marker?: never }); +>ParserName : Symbol(ParserName, Decl(emptyMappedParserMetadata.ts, 0, 0)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>marker : Symbol(marker, Decl(emptyMappedParserMetadata.ts, 0, 52)) + +declare const customParser: string; +>customParser : Symbol(customParser, Decl(emptyMappedParserMetadata.ts, 2, 13)) + +const parser: ParserName = customParser; +>parser : Symbol(parser, Decl(emptyMappedParserMetadata.ts, 3, 5)) +>ParserName : Symbol(ParserName, Decl(emptyMappedParserMetadata.ts, 0, 0)) +>customParser : Symbol(customParser, Decl(emptyMappedParserMetadata.ts, 2, 13)) + +const svelteParser: ParserName = "svelte"; +>svelteParser : Symbol(svelteParser, Decl(emptyMappedParserMetadata.ts, 4, 5)) +>ParserName : Symbol(ParserName, Decl(emptyMappedParserMetadata.ts, 0, 0)) + diff --git a/tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.types b/tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.types new file mode 100644 index 0000000000000..3f63bbefe1d3c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/emptyMappedParserMetadata.types @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/emptyMappedParserMetadata.ts] //// + +=== emptyMappedParserMetadata.ts === +type ParserName = "babel" | (Pick & { marker?: never }); +>ParserName : ParserName +>marker : undefined + +declare const customParser: string; +>customParser : string + +const parser: ParserName = customParser; +>parser : ParserName +>customParser : string + +const svelteParser: ParserName = "svelte"; +>svelteParser : ParserName +>"svelte" : "svelte" + diff --git a/tsc/testdata/tests/cases/compiler/emptyMappedParserMetadata.ts b/tsc/testdata/tests/cases/compiler/emptyMappedParserMetadata.ts new file mode 100644 index 0000000000000..7129991ce7483 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/emptyMappedParserMetadata.ts @@ -0,0 +1,8 @@ +// @strict: true +// @noEmit: true + +type ParserName = "babel" | (Pick & { marker?: never }); + +declare const customParser: string; +const parser: ParserName = customParser; +const svelteParser: ParserName = "svelte"; From 6a3b38c5dc34e1676825be2f18e3b7102abd97fd Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:47:21 -0700 Subject: [PATCH 020/116] Add historical coverage: empty mapped jsx props Exact original PR before56a08250 clean/head0b454af TS2559; report-adjacent main3ba257ff clean plus exact checker patch TS2559; native current clean. Redux BlockUpdates has Readonly<{}> props intersected with optional JSX intrinsic attributes. This characterizes currently accepted JSX children, not a claim React declares children or that stricter checking is necessarily a bug. Existing jsxCallbackWithDestructuring and jsxElementClassTooManyParams stay clean before/after. Reconstruction is not recovered bot artifact. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021425964 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/emptyMappedJsxProps.symbols | 33 +++++++++++++++++++ .../compiler/emptyMappedJsxProps.types | 27 +++++++++++++++ .../cases/compiler/emptyMappedJsxProps.tsx | 15 +++++++++ 3 files changed, 75 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.types create mode 100644 tsc/testdata/tests/cases/compiler/emptyMappedJsxProps.tsx diff --git a/tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.symbols b/tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.symbols new file mode 100644 index 0000000000000..dd97e12de8c4d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.symbols @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/emptyMappedJsxProps.tsx] //// + +=== emptyMappedJsxProps.tsx === +declare namespace JSX { +>JSX : Symbol(JSX, Decl(emptyMappedJsxProps.tsx, 0, 0)) + + interface Element {} +>Element : Symbol(Element, Decl(emptyMappedJsxProps.tsx, 0, 23)) + + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(emptyMappedJsxProps.tsx, 1, 24)) +>props : Symbol(ElementAttributesProperty.props, Decl(emptyMappedJsxProps.tsx, 2, 41)) + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(emptyMappedJsxProps.tsx, 2, 54)) +>children : Symbol(ElementChildrenAttribute.children, Decl(emptyMappedJsxProps.tsx, 3, 40)) + + interface IntrinsicAttributes { key?: string; } +>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(emptyMappedJsxProps.tsx, 3, 56)) +>key : Symbol(IntrinsicAttributes.key, Decl(emptyMappedJsxProps.tsx, 4, 35)) +} + +class Component { +>Component : Symbol(Component, Decl(emptyMappedJsxProps.tsx, 5, 1)) + + props: Readonly<{}> = {}; +>props : Symbol(Component.props, Decl(emptyMappedJsxProps.tsx, 7, 17)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +} +content; +>Component : Symbol(Component, Decl(emptyMappedJsxProps.tsx, 5, 1)) +>Component : Symbol(Component, Decl(emptyMappedJsxProps.tsx, 5, 1)) + diff --git a/tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.types b/tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.types new file mode 100644 index 0000000000000..675179090750b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/emptyMappedJsxProps.types @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/emptyMappedJsxProps.tsx] //// + +=== emptyMappedJsxProps.tsx === +declare namespace JSX { + interface Element {} + interface ElementAttributesProperty { props: {}; } +>props : {} + + interface ElementChildrenAttribute { children: {}; } +>children : {} + + interface IntrinsicAttributes { key?: string; } +>key : string | undefined +} + +class Component { +>Component : Component + + props: Readonly<{}> = {}; +>props : Readonly<{}> +>{} : {} +} +content; +>content : JSX.Element +>Component : typeof Component +>Component : typeof Component + diff --git a/tsc/testdata/tests/cases/compiler/emptyMappedJsxProps.tsx b/tsc/testdata/tests/cases/compiler/emptyMappedJsxProps.tsx new file mode 100644 index 0000000000000..3f65298810159 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/emptyMappedJsxProps.tsx @@ -0,0 +1,15 @@ +// @strict: true +// @jsx: preserve +// @noEmit: true + +declare namespace JSX { + interface Element {} + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + interface IntrinsicAttributes { key?: string; } +} + +class Component { + props: Readonly<{}> = {}; +} +content; From 465d4dace3e491f3e702199e8434f6bc871d3c27 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:47:24 -0700 Subject: [PATCH 021/116] Add historical coverage: schema callable return metadata Exact original PR before56a08250 clean/head0b454af two TS2416; report-adjacent main3ba257ff clean plus exact checker patch two TS2416; native current clean. Actual Yup Test OPTIONS property is optional, while Schema.asNestedTest returns plain RunTest. Minimal interface, callback intersection and inferred-this resolve return preserve direct method mismatch and recursively propagated mismatch. No invented required metadata property or cast masks the relation. Reconstruction is not recovered bot artifact. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021425964 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../schemaCallableReturnMetadata.symbols | 31 +++++++++++++++++++ .../schemaCallableReturnMetadata.types | 27 ++++++++++++++++ .../compiler/schemaCallableReturnMetadata.ts | 13 ++++++++ 3 files changed, 71 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.types create mode 100644 tsc/testdata/tests/cases/compiler/schemaCallableReturnMetadata.ts diff --git a/tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.symbols b/tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.symbols new file mode 100644 index 0000000000000..d9fc2340c6de1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.symbols @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/schemaCallableReturnMetadata.ts] //// + +=== schemaCallableReturnMetadata.ts === +type Test = (() => void) & { options?: {} }; +>Test : Symbol(Test, Decl(schemaCallableReturnMetadata.ts, 0, 0)) +>options : Symbol(options, Decl(schemaCallableReturnMetadata.ts, 0, 28)) + +interface ISchema { +>ISchema : Symbol(ISchema, Decl(schemaCallableReturnMetadata.ts, 0, 44)) + + resolve(): ISchema; +>resolve : Symbol(ISchema.resolve, Decl(schemaCallableReturnMetadata.ts, 1, 19)) +>ISchema : Symbol(ISchema, Decl(schemaCallableReturnMetadata.ts, 0, 44)) + + asNestedTest(): Test; +>asNestedTest : Symbol(ISchema.asNestedTest, Decl(schemaCallableReturnMetadata.ts, 2, 23)) +>Test : Symbol(Test, Decl(schemaCallableReturnMetadata.ts, 0, 0)) +} + +class Schema implements ISchema { +>Schema : Symbol(Schema, Decl(schemaCallableReturnMetadata.ts, 4, 1)) +>ISchema : Symbol(ISchema, Decl(schemaCallableReturnMetadata.ts, 0, 44)) + + resolve() { return this; } +>resolve : Symbol(Schema.resolve, Decl(schemaCallableReturnMetadata.ts, 6, 33)) +>this : Symbol(Schema, Decl(schemaCallableReturnMetadata.ts, 4, 1)) + + asNestedTest(): () => void { return () => {}; } +>asNestedTest : Symbol(Schema.asNestedTest, Decl(schemaCallableReturnMetadata.ts, 7, 30)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.types b/tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.types new file mode 100644 index 0000000000000..e76b0e7b3ccc2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/schemaCallableReturnMetadata.types @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/schemaCallableReturnMetadata.ts] //// + +=== schemaCallableReturnMetadata.ts === +type Test = (() => void) & { options?: {} }; +>Test : Test +>options : {} | undefined + +interface ISchema { + resolve(): ISchema; +>resolve : () => ISchema + + asNestedTest(): Test; +>asNestedTest : () => Test +} + +class Schema implements ISchema { +>Schema : Schema + + resolve() { return this; } +>resolve : () => this +>this : this + + asNestedTest(): () => void { return () => {}; } +>asNestedTest : () => () => void +>() => {} : () => void +} + diff --git a/tsc/testdata/tests/cases/compiler/schemaCallableReturnMetadata.ts b/tsc/testdata/tests/cases/compiler/schemaCallableReturnMetadata.ts new file mode 100644 index 0000000000000..00d118c80d9c7 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/schemaCallableReturnMetadata.ts @@ -0,0 +1,13 @@ +// @strict: true +// @noEmit: true + +type Test = (() => void) & { options?: {} }; +interface ISchema { + resolve(): ISchema; + asNestedTest(): Test; +} + +class Schema implements ISchema { + resolve() { return this; } + asNestedTest(): () => void { return () => {}; } +} From db1aac80a8b7c779ce6e178385fb9d9a75237fa8 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 13:47:27 -0700 Subject: [PATCH 022/116] Add historical coverage: default types exclude ambient packages Exact original PR source checkers: basea88d4c1ec3754b3c374d6a869679fbd6c9ba7717 implicitly loads a tiny synthetic ambient package and is clean; head3f2b3839f05fef7d55c35be15d2a455988e35b97 omits it and reports source-matching TS2304 for __dirname. Explicit named types control remains clean before/after; existing moduleResolution_noLeadingDot remains clean and does not exercise omitted default ambient packages. Conventional-changelog's pinned tools and inherited root configs omit types. Fixed unchanged JS6.0.3 ES2015 libraries; current native also reports only TS2304. Fixture has one self-contained ambient declaration, no external library imports. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63054#issuecomment-3808836035 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../defaultTypesExcludeAmbientPackages.errors.txt | 11 +++++++++++ .../defaultTypesExcludeAmbientPackages.symbols | 6 ++++++ .../compiler/defaultTypesExcludeAmbientPackages.types | 6 ++++++ .../compiler/defaultTypesExcludeAmbientPackages.ts | 11 +++++++++++ 4 files changed, 34 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.errors.txt b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.errors.txt new file mode 100644 index 0000000000000..f505bd432cffc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.errors.txt @@ -0,0 +1,11 @@ +/main.ts(1,1): error TS2304: Cannot find name '__dirname'. + + +==== /main.ts (1 errors) ==== + __dirname; + ~~~~~~~~~ +!!! error TS2304: Cannot find name '__dirname'. + +==== /node_modules/@types/runtime/index.d.ts (0 errors) ==== + declare const __dirname: string; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.symbols b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.symbols new file mode 100644 index 0000000000000..6aff4ee8da081 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.symbols @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts] //// + +=== /main.ts === + +__dirname; + diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.types b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.types new file mode 100644 index 0000000000000..667d58b9fd911 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientPackages.types @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts] //// + +=== /main.ts === +__dirname; +>__dirname : any + diff --git a/tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts new file mode 100644 index 0000000000000..ddfc4e3d48633 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts @@ -0,0 +1,11 @@ +// @target: es2015 +// @strict: true +// @noEmit: true +// @noImplicitReferences: true +// @currentDirectory: / + +// @filename: /node_modules/@types/runtime/index.d.ts +declare const __dirname: string; + +// @filename: /main.ts +__dirname; From 27ab929f7f7228e23a7b8603fb118693a17bfde6 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 14:00:03 -0700 Subject: [PATCH 023/116] Add historical coverage: default types exclude library references Exact original before/head compilers with fixed standard libraries: implicit ambient package loads referenced ES2018 before, so string-array includes is clean; after omits package and emits sole TS2550. Explicit named-types control remains clean before/after; native current emits sole TS2550. Pinned actions source/config/lock and actually selected Node14.0.1 ts3.7/base.d.ts demonstrate the same transitive standard-library chain. Existing wildcard discovery and explicit source lib-reference cases do not exercise omitted automatic package discovery. One synthetic reference-only declaration, no external imports or copied library declarations. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63054#issuecomment-3808836035 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../defaultTypesExcludeLibraryReferences.errors.txt | 11 +++++++++++ .../defaultTypesExcludeLibraryReferences.symbols | 6 ++++++ .../defaultTypesExcludeLibraryReferences.types | 11 +++++++++++ .../compiler/defaultTypesExcludeLibraryReferences.ts | 9 +++++++++ 4 files changed, 37 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.errors.txt b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.errors.txt new file mode 100644 index 0000000000000..47cd0667c4995 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.errors.txt @@ -0,0 +1,11 @@ +/main.ts(1,18): error TS2550: Property 'includes' does not exist on type 'string[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2016' or later. + + +==== /main.ts (1 errors) ==== + ["workflow.yml"].includes("workflow.yml"); + ~~~~~~~~ +!!! error TS2550: Property 'includes' does not exist on type 'string[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2016' or later. + +==== /node_modules/@types/runtime/index.d.ts (0 errors) ==== + /// + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.symbols b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.symbols new file mode 100644 index 0000000000000..e3e9f712e2b06 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.symbols @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts] //// + +=== /main.ts === + +["workflow.yml"].includes("workflow.yml"); + diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.types b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.types new file mode 100644 index 0000000000000..e693b144f12df --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeLibraryReferences.types @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts] //// + +=== /main.ts === +["workflow.yml"].includes("workflow.yml"); +>["workflow.yml"].includes("workflow.yml") : any +>["workflow.yml"].includes : any +>["workflow.yml"] : string[] +>"workflow.yml" : "workflow.yml" +>includes : any +>"workflow.yml" : "workflow.yml" + diff --git a/tsc/testdata/tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts new file mode 100644 index 0000000000000..e0d3d6ff97427 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts @@ -0,0 +1,9 @@ +// @target: es2015 +// @noEmit: true +// @noImplicitReferences: true + +// @filename: /node_modules/@types/runtime/index.d.ts +/// + +// @filename: /main.ts +["workflow.yml"].includes("workflow.yml"); From 1720b2fea264e2e42215e64787aef3b8b7f12a81 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 14:08:47 -0700 Subject: [PATCH 024/116] Add historical coverage: callable constructor union metadata Exact original before56a08250 clean/head0b454af TS2322; independently reconstructed report-adjacent main3ba257ff clean/main plus exact checker patch TS2322; native current clean. Actual RJSF Field is function-or-constructor ComponentType intersected with optional metadata; generic callable assignment retains union relation, unlike plain callable case. Twelve source-confirmed identities only; constructor-as-PropertyDescriptor pair excluded. Existing inference cases keep prior diagnostics. Reconstruction is not recovered bot artifact. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021426776 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../callableConstructorUnionMetadata.symbols | 29 +++++++++++++++++++ .../callableConstructorUnionMetadata.types | 20 +++++++++++++ .../callableConstructorUnionMetadata.ts | 8 +++++ 3 files changed, 57 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.types create mode 100644 tsc/testdata/tests/cases/compiler/callableConstructorUnionMetadata.ts diff --git a/tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.symbols b/tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.symbols new file mode 100644 index 0000000000000..b5947d185c8a7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/callableConstructorUnionMetadata.ts] //// + +=== callableConstructorUnionMetadata.ts === +type Component = ((props: Props) => number) | (new (props: Props) => object); +>Component : Symbol(Component, Decl(callableConstructorUnionMetadata.ts, 0, 0)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 0, 15)) +>props : Symbol(props, Decl(callableConstructorUnionMetadata.ts, 0, 26)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 0, 15)) +>props : Symbol(props, Decl(callableConstructorUnionMetadata.ts, 0, 59)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 0, 15)) + +type Field = Component & { testIds?: {} }; +>Field : Symbol(Field, Decl(callableConstructorUnionMetadata.ts, 0, 84)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 1, 11)) +>Component : Symbol(Component, Decl(callableConstructorUnionMetadata.ts, 0, 0)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 1, 11)) +>testIds : Symbol(testIds, Decl(callableConstructorUnionMetadata.ts, 1, 40)) + +declare const component: (props: Props) => number; +>component : Symbol(component, Decl(callableConstructorUnionMetadata.ts, 3, 13)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 3, 26)) +>props : Symbol(props, Decl(callableConstructorUnionMetadata.ts, 3, 33)) +>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 3, 26)) + +const field: Field = component; +>field : Symbol(field, Decl(callableConstructorUnionMetadata.ts, 4, 5)) +>Field : Symbol(Field, Decl(callableConstructorUnionMetadata.ts, 0, 84)) +>component : Symbol(component, Decl(callableConstructorUnionMetadata.ts, 3, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.types b/tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.types new file mode 100644 index 0000000000000..d9ea9c9fdabfa --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/callableConstructorUnionMetadata.types @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/callableConstructorUnionMetadata.ts] //// + +=== callableConstructorUnionMetadata.ts === +type Component = ((props: Props) => number) | (new (props: Props) => object); +>Component : Component +>props : Props +>props : Props + +type Field = Component & { testIds?: {} }; +>Field : Field +>testIds : {} | undefined + +declare const component: (props: Props) => number; +>component : (props: Props) => number +>props : Props + +const field: Field = component; +>field : Field +>component : (props: Props) => number + diff --git a/tsc/testdata/tests/cases/compiler/callableConstructorUnionMetadata.ts b/tsc/testdata/tests/cases/compiler/callableConstructorUnionMetadata.ts new file mode 100644 index 0000000000000..5e07e809245f3 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/callableConstructorUnionMetadata.ts @@ -0,0 +1,8 @@ +// @strict: true +// @noEmit: true + +type Component = ((props: Props) => number) | (new (props: Props) => object); +type Field = Component & { testIds?: {} }; + +declare const component: (props: Props) => number; +const field: Field = component; From eeddfad02a5459013386409c60ba04d35a134cbb Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 14:08:51 -0700 Subject: [PATCH 025/116] Add historical coverage: declaration default import suggestion Exact original before9c4c3770 clean/head6ee5131f sole source-matching TS2613 named-import suggestion. Actual SQLite declaration exports an interface matching the default import binding; minimal relative declaration preserves precisely that lookup. Existing allowSyntheticDefaultImports1 produces TS1192 but not suggestion branch. Native current clean baseline. No external imports, copied declarations or suppressions. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62530#issuecomment-3362939548 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../declarationDefaultImportSuggestion.symbols | 10 ++++++++++ .../compiler/declarationDefaultImportSuggestion.types | 10 ++++++++++ .../compiler/declarationDefaultImportSuggestion.ts | 10 ++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.types create mode 100644 tsc/testdata/tests/cases/compiler/declarationDefaultImportSuggestion.ts diff --git a/tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.symbols b/tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.symbols new file mode 100644 index 0000000000000..ed9f45a318148 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/declarationDefaultImportSuggestion.ts] //// + +=== store.d.ts === +export interface Store {} +>Store : Symbol(Store, Decl(store.d.ts, 0, 0)) + +=== main.ts === +import Store from "./store"; +>Store : Symbol(Store, Decl(main.ts, 0, 6)) + diff --git a/tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.types b/tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.types new file mode 100644 index 0000000000000..b997663115396 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/declarationDefaultImportSuggestion.types @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/declarationDefaultImportSuggestion.ts] //// + +=== store.d.ts === + +export interface Store {} + +=== main.ts === +import Store from "./store"; +>Store : typeof Store + diff --git a/tsc/testdata/tests/cases/compiler/declarationDefaultImportSuggestion.ts b/tsc/testdata/tests/cases/compiler/declarationDefaultImportSuggestion.ts new file mode 100644 index 0000000000000..af1204de45940 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/declarationDefaultImportSuggestion.ts @@ -0,0 +1,10 @@ +// @target: es2015 +// @module: commonjs +// @allowSyntheticDefaultImports: true +// @noEmit: true + +// @filename: store.d.ts +export interface Store {} + +// @filename: main.ts +import Store from "./store"; From 778b159b0c0309ec8060cb1fda3b073ebb10bb8c Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 14:08:54 -0700 Subject: [PATCH 026/116] Add historical coverage: type only synthetic default import Exact original before9c4c3770 clean/head6ee5131f sole TS2305 for source-shaped import type {default as Library} plus typeof alias. Existing named value import catches general guard but not the type-only source form; original typeOnly/exportDefault and importEquals1 both keep their four prior diagnostic sets. Tiny relative function declaration replaces real library; native current clean baseline. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62530#issuecomment-3362939548 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../typeOnlySyntheticDefaultImport.symbols | 15 +++++++++++++++ .../compiler/typeOnlySyntheticDefaultImport.types | 15 +++++++++++++++ .../compiler/typeOnlySyntheticDefaultImport.ts | 11 +++++++++++ 3 files changed, 41 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.types create mode 100644 tsc/testdata/tests/cases/compiler/typeOnlySyntheticDefaultImport.ts diff --git a/tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.symbols b/tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.symbols new file mode 100644 index 0000000000000..5f0daa00b8b8f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/typeOnlySyntheticDefaultImport.ts] //// + +=== library.d.ts === +export function render(): void; +>render : Symbol(render, Decl(library.d.ts, 0, 0)) + +=== main.ts === +import type { default as Library } from "./library"; +>default : Symbol(Library, Decl(library.d.ts, 0, 0)) +>Library : Symbol(Library, Decl(main.ts, 0, 13)) + +type LibraryType = typeof Library; +>LibraryType : Symbol(LibraryType, Decl(main.ts, 0, 52)) +>Library : Symbol(Library, Decl(main.ts, 0, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.types b/tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.types new file mode 100644 index 0000000000000..478a80931725f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/typeOnlySyntheticDefaultImport.types @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/typeOnlySyntheticDefaultImport.ts] //// + +=== library.d.ts === +export function render(): void; +>render : () => void + +=== main.ts === +import type { default as Library } from "./library"; +>default : typeof Library +>Library : any + +type LibraryType = typeof Library; +>LibraryType : typeof Library +>Library : typeof Library + diff --git a/tsc/testdata/tests/cases/compiler/typeOnlySyntheticDefaultImport.ts b/tsc/testdata/tests/cases/compiler/typeOnlySyntheticDefaultImport.ts new file mode 100644 index 0000000000000..5309149f3dd97 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/typeOnlySyntheticDefaultImport.ts @@ -0,0 +1,11 @@ +// @target: es2015 +// @module: commonjs +// @allowSyntheticDefaultImports: true +// @noEmit: true + +// @filename: library.d.ts +export function render(): void; + +// @filename: main.ts +import type { default as Library } from "./library"; +type LibraryType = typeof Library; From 44ca74ca691aaa7e45ab37ad919b113029c41875 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 14:26:48 -0700 Subject: [PATCH 027/116] Add historical coverage: generic value marker Exact original before56a08250 clean/head0b454af sole TS2345; independently reconstructed report-adjacent main clean/main plus exact checker patch TS2345; native current clean. Published pinned Vitest1.6.1 Expected & AValue value overload retains generic inference through optional unique-symbol object or primitive union. Eighteen actual Reselect direct call identities only; overload variants excluded. Existing unionTypeInference retains two prior diagnostics. Reconstruction is not recovered bot artifact. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021426646 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/genericValueMarker.symbols | 21 +++++++++++++++++++ .../compiler/genericValueMarker.types | 21 +++++++++++++++++++ .../cases/compiler/genericValueMarker.ts | 7 +++++++ 3 files changed, 49 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/genericValueMarker.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/genericValueMarker.types create mode 100644 tsc/testdata/tests/cases/compiler/genericValueMarker.ts diff --git a/tsc/testdata/baselines/reference/compiler/genericValueMarker.symbols b/tsc/testdata/baselines/reference/compiler/genericValueMarker.symbols new file mode 100644 index 0000000000000..b2ff90d724129 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericValueMarker.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/genericValueMarker.ts] //// + +=== genericValueMarker.ts === +declare const valueMarker: unique symbol; +>valueMarker : Symbol(valueMarker, Decl(genericValueMarker.ts, 0, 13)) + +type AnyValue = { [valueMarker]?: undefined } | number; +>AnyValue : Symbol(AnyValue, Decl(genericValueMarker.ts, 0, 41)) +>[valueMarker] : Symbol([valueMarker], Decl(genericValueMarker.ts, 1, 17)) +>valueMarker : Symbol(valueMarker, Decl(genericValueMarker.ts, 0, 13)) + +declare function compare(value: Value & AnyValue): void; +>compare : Symbol(compare, Decl(genericValueMarker.ts, 1, 55)) +>Value : Symbol(Value, Decl(genericValueMarker.ts, 2, 25)) +>value : Symbol(value, Decl(genericValueMarker.ts, 2, 32)) +>Value : Symbol(Value, Decl(genericValueMarker.ts, 2, 25)) +>AnyValue : Symbol(AnyValue, Decl(genericValueMarker.ts, 0, 41)) + +compare((): number => 0); +>compare : Symbol(compare, Decl(genericValueMarker.ts, 1, 55)) + diff --git a/tsc/testdata/baselines/reference/compiler/genericValueMarker.types b/tsc/testdata/baselines/reference/compiler/genericValueMarker.types new file mode 100644 index 0000000000000..bf712a49552cf --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericValueMarker.types @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/genericValueMarker.ts] //// + +=== genericValueMarker.ts === +declare const valueMarker: unique symbol; +>valueMarker : unique symbol + +type AnyValue = { [valueMarker]?: undefined } | number; +>AnyValue : AnyValue +>[valueMarker] : undefined +>valueMarker : unique symbol + +declare function compare(value: Value & AnyValue): void; +>compare : (value: Value & AnyValue) => void +>value : Value & AnyValue + +compare((): number => 0); +>compare((): number => 0) : void +>compare : (value: Value & AnyValue) => void +>(): number => 0 : () => number +>0 : 0 + diff --git a/tsc/testdata/tests/cases/compiler/genericValueMarker.ts b/tsc/testdata/tests/cases/compiler/genericValueMarker.ts new file mode 100644 index 0000000000000..83f21e77888ae --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/genericValueMarker.ts @@ -0,0 +1,7 @@ +// @strict: true +// @noEmit: true + +declare const valueMarker: unique symbol; +type AnyValue = { [valueMarker]?: undefined } | number; +declare function compare(value: Value & AnyValue): void; +compare((): number => 0); From 4d77a586e14ccd5ff5c7dcb33dd0deac921881e2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 14:32:23 -0700 Subject: [PATCH 028/116] Add historical coverage: synthetic default callback context Exact pinned source AST verifies default event-stream alias, enclosing es.through function expression, exact reported this/parameter line and identifier. Actual pinned ambient module has named through with contextual callback this and data:any, no default/export assignment. Relative declaration reduction preserves optional write/end contextual signatures. Original before clean; head1192+7006+2683+2683. Other call forms are left pending; not whole-project rebuild or recovered refreshed bot merge. Existing declaration-default tests cover primary rejection but lack strict contextual callback receiver/parameter preservation. Fifty exact source-confirmed secondary identities; only matching es.through function expressions, not other VS Code/import fallout. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62530#issuecomment-3362940170 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../syntheticDefaultCallbackContext.symbols | 46 +++++++++++++++++ .../syntheticDefaultCallbackContext.types | 49 +++++++++++++++++++ .../syntheticDefaultCallbackContext.ts | 18 +++++++ 3 files changed, 113 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.types create mode 100644 tsc/testdata/tests/cases/compiler/syntheticDefaultCallbackContext.ts diff --git a/tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.symbols b/tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.symbols new file mode 100644 index 0000000000000..8872f8755005a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.symbols @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/syntheticDefaultCallbackContext.ts] //// + +=== stream.d.ts === +export interface Stream { +>Stream : Symbol(Stream, Decl(stream.d.ts, 0, 0)) + + emit(event: string, data?: any): void; +>emit : Symbol(Stream.emit, Decl(stream.d.ts, 0, 25)) +>event : Symbol(event, Decl(stream.d.ts, 1, 9)) +>data : Symbol(data, Decl(stream.d.ts, 1, 23)) +} +export function through(write?: (this: Stream, data: any) => void, end?: (this: Stream) => void): Stream; +>through : Symbol(through, Decl(stream.d.ts, 2, 1)) +>write : Symbol(write, Decl(stream.d.ts, 3, 24)) +>this : Symbol(this, Decl(stream.d.ts, 3, 33)) +>Stream : Symbol(Stream, Decl(stream.d.ts, 0, 0)) +>data : Symbol(data, Decl(stream.d.ts, 3, 46)) +>end : Symbol(end, Decl(stream.d.ts, 3, 66)) +>this : Symbol(this, Decl(stream.d.ts, 3, 74)) +>Stream : Symbol(Stream, Decl(stream.d.ts, 0, 0)) +>Stream : Symbol(Stream, Decl(stream.d.ts, 0, 0)) + +=== main.ts === +import stream from "./stream"; +>stream : Symbol(stream, Decl(main.ts, 0, 6)) + +stream.through(function (data) { +>stream.through : Symbol(stream.through, Decl(stream.d.ts, 2, 1)) +>stream : Symbol(stream, Decl(main.ts, 0, 6)) +>through : Symbol(stream.through, Decl(stream.d.ts, 2, 1)) +>data : Symbol(data, Decl(main.ts, 1, 25)) + + this.emit("data", data); +>this.emit : Symbol(stream.Stream.emit, Decl(stream.d.ts, 0, 25)) +>this : Symbol(this, Decl(stream.d.ts, 3, 33)) +>emit : Symbol(stream.Stream.emit, Decl(stream.d.ts, 0, 25)) +>data : Symbol(data, Decl(main.ts, 1, 25)) + +}, function () { + this.emit("end"); +>this.emit : Symbol(stream.Stream.emit, Decl(stream.d.ts, 0, 25)) +>this : Symbol(this, Decl(stream.d.ts, 3, 74)) +>emit : Symbol(stream.Stream.emit, Decl(stream.d.ts, 0, 25)) + +}); + diff --git a/tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.types b/tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.types new file mode 100644 index 0000000000000..f25a0e1703c11 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/syntheticDefaultCallbackContext.types @@ -0,0 +1,49 @@ +//// [tests/cases/compiler/syntheticDefaultCallbackContext.ts] //// + +=== stream.d.ts === +export interface Stream { + emit(event: string, data?: any): void; +>emit : (event: string, data?: any) => void +>event : string +>data : any +} +export function through(write?: (this: Stream, data: any) => void, end?: (this: Stream) => void): Stream; +>through : (write?: (this: Stream, data: any) => void, end?: (this: Stream) => void) => Stream +>write : ((this: Stream, data: any) => void) | undefined +>this : Stream +>data : any +>end : ((this: Stream) => void) | undefined +>this : Stream + +=== main.ts === +import stream from "./stream"; +>stream : typeof stream + +stream.through(function (data) { +>stream.through(function (data) { this.emit("data", data);}, function () { this.emit("end");}) : stream.Stream +>stream.through : (write?: (this: stream.Stream, data: any) => void, end?: (this: stream.Stream) => void) => stream.Stream +>stream : typeof stream +>through : (write?: (this: stream.Stream, data: any) => void, end?: (this: stream.Stream) => void) => stream.Stream +>function (data) { this.emit("data", data);} : (this: stream.Stream, data: any) => void +>data : any + + this.emit("data", data); +>this.emit("data", data) : void +>this.emit : (event: string, data?: any) => void +>this : stream.Stream +>emit : (event: string, data?: any) => void +>"data" : "data" +>data : any + +}, function () { +>function () { this.emit("end");} : (this: stream.Stream) => void + + this.emit("end"); +>this.emit("end") : void +>this.emit : (event: string, data?: any) => void +>this : stream.Stream +>emit : (event: string, data?: any) => void +>"end" : "end" + +}); + diff --git a/tsc/testdata/tests/cases/compiler/syntheticDefaultCallbackContext.ts b/tsc/testdata/tests/cases/compiler/syntheticDefaultCallbackContext.ts new file mode 100644 index 0000000000000..af20053a8b902 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/syntheticDefaultCallbackContext.ts @@ -0,0 +1,18 @@ +// @strict: true +// @noEmit: true +// @module: commonjs +// @allowSyntheticDefaultImports: true + +// @filename: stream.d.ts +export interface Stream { + emit(event: string, data?: any): void; +} +export function through(write?: (this: Stream, data: any) => void, end?: (this: Stream) => void): Stream; + +// @filename: main.ts +import stream from "./stream"; +stream.through(function (data) { + this.emit("data", data); +}, function () { + this.emit("end"); +}); From d3bbb332f06c3009bd3e7cab2a03cefe91a378ff Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 15:03:16 -0700 Subject: [PATCH 029/116] Add historical coverage: route component metadata Exact original before56a08250 clean/head0b454af2322+2339; reconstructed report-adjacent main clean/main plus exact patch2322+2339; native current clean. Actual router1.19.1 callable/lazy-callable union with required readonly $$typeof and optional preload, plus context-sensitive validator/default empty Search inference. Ten component AST nodes and two page bindings verified. Existing actual lazy-component React fixture retains0/0 under original JSX/bundler settings. No constructor-union substitution, libraries or copied declaration bundles. Reconstruction is not recovered bot artifact. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021426776 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/routeComponentMetadata.symbols | 49 ++++++++++++++++++ .../compiler/routeComponentMetadata.types | 50 +++++++++++++++++++ .../cases/compiler/routeComponentMetadata.ts | 9 ++++ 3 files changed, 108 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/routeComponentMetadata.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/routeComponentMetadata.types create mode 100644 tsc/testdata/tests/cases/compiler/routeComponentMetadata.ts diff --git a/tsc/testdata/baselines/reference/compiler/routeComponentMetadata.symbols b/tsc/testdata/baselines/reference/compiler/routeComponentMetadata.symbols new file mode 100644 index 0000000000000..b0837e66304fc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/routeComponentMetadata.symbols @@ -0,0 +1,49 @@ +//// [tests/cases/compiler/routeComponentMetadata.ts] //// + +=== routeComponentMetadata.ts === +type Component = (() => number) | ((() => number) & { readonly $$typeof: symbol }); +>Component : Symbol(Component, Decl(routeComponentMetadata.ts, 0, 0)) +>$$typeof : Symbol($$typeof, Decl(routeComponentMetadata.ts, 0, 53)) + +type RouteComponent = Component & { preload?: () => Promise }; +>RouteComponent : Symbol(RouteComponent, Decl(routeComponentMetadata.ts, 0, 83)) +>Component : Symbol(Component, Decl(routeComponentMetadata.ts, 0, 0)) +>preload : Symbol(preload, Decl(routeComponentMetadata.ts, 1, 35)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) + +declare function createRoute(options: { component?: RouteComponent; validateSearch?: (search: unknown) => Search }): { useSearch(): Search }; +>createRoute : Symbol(createRoute, Decl(routeComponentMetadata.ts, 1, 68)) +>Search : Symbol(Search, Decl(routeComponentMetadata.ts, 2, 29)) +>options : Symbol(options, Decl(routeComponentMetadata.ts, 2, 42)) +>component : Symbol(component, Decl(routeComponentMetadata.ts, 2, 52)) +>RouteComponent : Symbol(RouteComponent, Decl(routeComponentMetadata.ts, 0, 83)) +>validateSearch : Symbol(validateSearch, Decl(routeComponentMetadata.ts, 2, 80)) +>search : Symbol(search, Decl(routeComponentMetadata.ts, 2, 99)) +>Search : Symbol(Search, Decl(routeComponentMetadata.ts, 2, 29)) +>useSearch : Symbol(useSearch, Decl(routeComponentMetadata.ts, 2, 131)) +>Search : Symbol(Search, Decl(routeComponentMetadata.ts, 2, 29)) + +declare const schema: { parse(search: unknown): { page: number } }; +>schema : Symbol(schema, Decl(routeComponentMetadata.ts, 3, 13)) +>parse : Symbol(parse, Decl(routeComponentMetadata.ts, 3, 23)) +>search : Symbol(search, Decl(routeComponentMetadata.ts, 3, 30)) +>page : Symbol(page, Decl(routeComponentMetadata.ts, 3, 49)) + +const route = createRoute({ component: () => 0, validateSearch: search => schema.parse(search) }); +>route : Symbol(route, Decl(routeComponentMetadata.ts, 4, 5)) +>createRoute : Symbol(createRoute, Decl(routeComponentMetadata.ts, 1, 68)) +>component : Symbol(component, Decl(routeComponentMetadata.ts, 4, 27)) +>validateSearch : Symbol(validateSearch, Decl(routeComponentMetadata.ts, 4, 47)) +>search : Symbol(search, Decl(routeComponentMetadata.ts, 4, 63)) +>schema.parse : Symbol(parse, Decl(routeComponentMetadata.ts, 3, 23)) +>schema : Symbol(schema, Decl(routeComponentMetadata.ts, 3, 13)) +>parse : Symbol(parse, Decl(routeComponentMetadata.ts, 3, 23)) +>search : Symbol(search, Decl(routeComponentMetadata.ts, 4, 63)) + +route.useSearch().page; +>route.useSearch().page : Symbol(page, Decl(routeComponentMetadata.ts, 3, 49)) +>route.useSearch : Symbol(useSearch, Decl(routeComponentMetadata.ts, 2, 131)) +>route : Symbol(route, Decl(routeComponentMetadata.ts, 4, 5)) +>useSearch : Symbol(useSearch, Decl(routeComponentMetadata.ts, 2, 131)) +>page : Symbol(page, Decl(routeComponentMetadata.ts, 3, 49)) + diff --git a/tsc/testdata/baselines/reference/compiler/routeComponentMetadata.types b/tsc/testdata/baselines/reference/compiler/routeComponentMetadata.types new file mode 100644 index 0000000000000..a5ae679a140c2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/routeComponentMetadata.types @@ -0,0 +1,50 @@ +//// [tests/cases/compiler/routeComponentMetadata.ts] //// + +=== routeComponentMetadata.ts === +type Component = (() => number) | ((() => number) & { readonly $$typeof: symbol }); +>Component : Component +>$$typeof : symbol + +type RouteComponent = Component & { preload?: () => Promise }; +>RouteComponent : RouteComponent +>preload : (() => Promise) | undefined + +declare function createRoute(options: { component?: RouteComponent; validateSearch?: (search: unknown) => Search }): { useSearch(): Search }; +>createRoute : (options: { component?: RouteComponent; validateSearch?: (search: unknown) => Search; }) => { useSearch(): Search; } +>options : { component?: RouteComponent; validateSearch?: (search: unknown) => Search; } +>component : RouteComponent | undefined +>validateSearch : ((search: unknown) => Search) | undefined +>search : unknown +>useSearch : () => Search + +declare const schema: { parse(search: unknown): { page: number } }; +>schema : { parse(search: unknown): { page: number; }; } +>parse : (search: unknown) => { page: number; } +>search : unknown +>page : number + +const route = createRoute({ component: () => 0, validateSearch: search => schema.parse(search) }); +>route : { useSearch(): { page: number; }; } +>createRoute({ component: () => 0, validateSearch: search => schema.parse(search) }) : { useSearch(): { page: number; }; } +>createRoute : (options: { component?: RouteComponent; validateSearch?: (search: unknown) => Search; }) => { useSearch(): Search; } +>{ component: () => 0, validateSearch: search => schema.parse(search) } : { component: () => number; validateSearch: (search: unknown) => { page: number; }; } +>component : () => number +>() => 0 : () => number +>0 : 0 +>validateSearch : (search: unknown) => { page: number; } +>search => schema.parse(search) : (search: unknown) => { page: number; } +>search : unknown +>schema.parse(search) : { page: number; } +>schema.parse : (search: unknown) => { page: number; } +>schema : { parse(search: unknown): { page: number; }; } +>parse : (search: unknown) => { page: number; } +>search : unknown + +route.useSearch().page; +>route.useSearch().page : number +>route.useSearch() : { page: number; } +>route.useSearch : () => { page: number; } +>route : { useSearch(): { page: number; }; } +>useSearch : () => { page: number; } +>page : number + diff --git a/tsc/testdata/tests/cases/compiler/routeComponentMetadata.ts b/tsc/testdata/tests/cases/compiler/routeComponentMetadata.ts new file mode 100644 index 0000000000000..3b4e14e75a151 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/routeComponentMetadata.ts @@ -0,0 +1,9 @@ +// @strict: true +// @noEmit: true + +type Component = (() => number) | ((() => number) & { readonly $$typeof: symbol }); +type RouteComponent = Component & { preload?: () => Promise }; +declare function createRoute(options: { component?: RouteComponent; validateSearch?: (search: unknown) => Search }): { useSearch(): Search }; +declare const schema: { parse(search: unknown): { page: number } }; +const route = createRoute({ component: () => 0, validateSearch: search => schema.parse(search) }); +route.useSearch().page; From f5f0fc1185a69ca22ed0dfec2fa74b66cc9ac6b8 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 15:27:56 -0700 Subject: [PATCH 030/116] Add historical coverage: component enhancer return Exact original and separately labeled report-adjacent reconstruction clean before, then2322/2322/2769; native clean. Bare outer enhancer returns callable/constructor component intersected with optional getInitialProps. Curried contextual props and actual Plugin reducer fallback preserved. Source pins Next14.2.28/15.3.1/15.3.4 verified; existing instantiateContextualTypes stays0/0. Four exact source identities, no external imports or copied libraries. Integrated interface renamed RenderPlugin to avoid ambient DOM Plugin merging; isolated ES5/types[] original and reconstructed pairs reverified with same diagnostic differential. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021426219 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/componentEnhancerReturn.symbols | 51 ++++++++++++++++++ .../compiler/componentEnhancerReturn.types | 53 +++++++++++++++++++ .../cases/compiler/componentEnhancerReturn.ts | 11 ++++ 3 files changed, 115 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.types create mode 100644 tsc/testdata/tests/cases/compiler/componentEnhancerReturn.ts diff --git a/tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.symbols b/tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.symbols new file mode 100644 index 0000000000000..716d37578aebf --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.symbols @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/componentEnhancerReturn.ts] //// + +=== componentEnhancerReturn.ts === +type Component = ((props: number) => number) | (new (props: number) => object); +>Component : Symbol(Component, Decl(componentEnhancerReturn.ts, 0, 0)) +>props : Symbol(props, Decl(componentEnhancerReturn.ts, 0, 19)) +>props : Symbol(props, Decl(componentEnhancerReturn.ts, 0, 53)) + +type App = Component & { getInitialProps?: () => object }; +>App : Symbol(App, Decl(componentEnhancerReturn.ts, 0, 79)) +>Component : Symbol(Component, Decl(componentEnhancerReturn.ts, 0, 0)) +>getInitialProps : Symbol(getInitialProps, Decl(componentEnhancerReturn.ts, 1, 24)) + +declare function render(enhance: (app: App) => App): void; +>render : Symbol(render, Decl(componentEnhancerReturn.ts, 1, 58)) +>enhance : Symbol(enhance, Decl(componentEnhancerReturn.ts, 2, 24)) +>app : Symbol(app, Decl(componentEnhancerReturn.ts, 2, 34)) +>App : Symbol(App, Decl(componentEnhancerReturn.ts, 0, 79)) +>App : Symbol(App, Decl(componentEnhancerReturn.ts, 0, 79)) + +render(app => props => props); +>render : Symbol(render, Decl(componentEnhancerReturn.ts, 1, 58)) +>app : Symbol(app, Decl(componentEnhancerReturn.ts, 3, 7)) +>props : Symbol(props, Decl(componentEnhancerReturn.ts, 3, 13)) +>props : Symbol(props, Decl(componentEnhancerReturn.ts, 3, 13)) + +interface RenderPlugin { enhance(app: Component): (props: number) => number } +>RenderPlugin : Symbol(RenderPlugin, Decl(componentEnhancerReturn.ts, 3, 30)) +>enhance : Symbol(RenderPlugin.enhance, Decl(componentEnhancerReturn.ts, 5, 24)) +>app : Symbol(app, Decl(componentEnhancerReturn.ts, 5, 33)) +>Component : Symbol(Component, Decl(componentEnhancerReturn.ts, 0, 0)) +>props : Symbol(props, Decl(componentEnhancerReturn.ts, 5, 51)) + +declare const plugins: RenderPlugin[]; +>plugins : Symbol(plugins, Decl(componentEnhancerReturn.ts, 6, 13)) +>RenderPlugin : Symbol(RenderPlugin, Decl(componentEnhancerReturn.ts, 3, 30)) + +render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app)); +>render : Symbol(render, Decl(componentEnhancerReturn.ts, 1, 58)) +>app : Symbol(app, Decl(componentEnhancerReturn.ts, 7, 7)) +>plugins.reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>plugins : Symbol(plugins, Decl(componentEnhancerReturn.ts, 6, 13)) +>reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>result : Symbol(result, Decl(componentEnhancerReturn.ts, 7, 30)) +>plugin : Symbol(plugin, Decl(componentEnhancerReturn.ts, 7, 37)) +>plugin.enhance : Symbol(RenderPlugin.enhance, Decl(componentEnhancerReturn.ts, 5, 24)) +>plugin : Symbol(plugin, Decl(componentEnhancerReturn.ts, 7, 37)) +>enhance : Symbol(RenderPlugin.enhance, Decl(componentEnhancerReturn.ts, 5, 24)) +>result : Symbol(result, Decl(componentEnhancerReturn.ts, 7, 30)) +>app : Symbol(app, Decl(componentEnhancerReturn.ts, 7, 7)) + diff --git a/tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.types b/tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.types new file mode 100644 index 0000000000000..a3049b18cb02c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/componentEnhancerReturn.types @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/componentEnhancerReturn.ts] //// + +=== componentEnhancerReturn.ts === +type Component = ((props: number) => number) | (new (props: number) => object); +>Component : Component +>props : number +>props : number + +type App = Component & { getInitialProps?: () => object }; +>App : App +>getInitialProps : (() => object) | undefined + +declare function render(enhance: (app: App) => App): void; +>render : (enhance: (app: App) => App) => void +>enhance : (app: App) => App +>app : App + +render(app => props => props); +>render(app => props => props) : void +>render : (enhance: (app: App) => App) => void +>app => props => props : (app: App) => (props: number) => number +>app : App +>props => props : (props: number) => number +>props : number +>props : number + +interface RenderPlugin { enhance(app: Component): (props: number) => number } +>enhance : (app: Component) => (props: number) => number +>app : Component +>props : number + +declare const plugins: RenderPlugin[]; +>plugins : RenderPlugin[] + +render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app)); +>render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app)) : void +>render : (enhance: (app: App) => App) => void +>app => plugins.reduce((result, plugin) => plugin.enhance(result), app) : (app: App) => App +>app : App +>plugins.reduce((result, plugin) => plugin.enhance(result), app) : App +>plugins.reduce : { (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin): RenderPlugin; (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin, initialValue: RenderPlugin): RenderPlugin; (callbackfn: (previousValue: U, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => U, initialValue: U): U; } +>plugins : RenderPlugin[] +>reduce : { (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin): RenderPlugin; (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin, initialValue: RenderPlugin): RenderPlugin; (callbackfn: (previousValue: U, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => U, initialValue: U): U; } +>(result, plugin) => plugin.enhance(result) : (result: App, plugin: RenderPlugin) => (props: number) => number +>result : App +>plugin : RenderPlugin +>plugin.enhance(result) : (props: number) => number +>plugin.enhance : (app: Component) => (props: number) => number +>plugin : RenderPlugin +>enhance : (app: Component) => (props: number) => number +>result : App +>app : App + diff --git a/tsc/testdata/tests/cases/compiler/componentEnhancerReturn.ts b/tsc/testdata/tests/cases/compiler/componentEnhancerReturn.ts new file mode 100644 index 0000000000000..58bf1af533a61 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/componentEnhancerReturn.ts @@ -0,0 +1,11 @@ +// @strict: true +// @noEmit: true + +type Component = ((props: number) => number) | (new (props: number) => object); +type App = Component & { getInitialProps?: () => object }; +declare function render(enhance: (app: App) => App): void; +render(app => props => props); + +interface RenderPlugin { enhance(app: Component): (props: number) => number } +declare const plugins: RenderPlugin[]; +render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app)); From e4b57a32c53cefdbc5e44a56400d32dbfc936cf7 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 15:28:01 -0700 Subject: [PATCH 031/116] Add historical coverage: template indexed scope options Exact original and separately labeled report-adjacent reconstruction clean before, then2345; native clean. Sequelize6.37.7 optional mapped attributes intersect template-key index signature; nonfresh method array is intentionally widened, so acceptance comes from indexed structural hash alternative, NOT tuple ScopeOptions. Four exact source identities; existing indexSignatures1 diagnostics unchanged52/52. No libraries, assertions or callable-metadata substitution. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60889#issuecomment-3021426219 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../templateIndexedScopeOptions.symbols | 23 +++++++++++++++ .../templateIndexedScopeOptions.types | 28 +++++++++++++++++++ .../compiler/templateIndexedScopeOptions.ts | 7 +++++ 3 files changed, 58 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.types create mode 100644 tsc/testdata/tests/cases/compiler/templateIndexedScopeOptions.ts diff --git a/tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.symbols b/tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.symbols new file mode 100644 index 0000000000000..9aad208ec6216 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/templateIndexedScopeOptions.ts] //// + +=== templateIndexedScopeOptions.ts === +type Attributes = { name?: string } & { [path: `$${string}.${string}$`]: unknown }; +>Attributes : Symbol(Attributes, Decl(templateIndexedScopeOptions.ts, 0, 0)) +>name : Symbol(name, Decl(templateIndexedScopeOptions.ts, 0, 19)) +>path : Symbol(path, Decl(templateIndexedScopeOptions.ts, 0, 41)) + +declare function scope(options: Attributes | { method: readonly [string, ...unknown[]] }): void; +>scope : Symbol(scope, Decl(templateIndexedScopeOptions.ts, 0, 83)) +>options : Symbol(options, Decl(templateIndexedScopeOptions.ts, 1, 23)) +>Attributes : Symbol(Attributes, Decl(templateIndexedScopeOptions.ts, 0, 0)) +>method : Symbol(method, Decl(templateIndexedScopeOptions.ts, 1, 46)) + +const options = { method: ["list", { id: 1 }] }; +>options : Symbol(options, Decl(templateIndexedScopeOptions.ts, 2, 5)) +>method : Symbol(method, Decl(templateIndexedScopeOptions.ts, 2, 17)) +>id : Symbol(id, Decl(templateIndexedScopeOptions.ts, 2, 36)) + +scope(options); +>scope : Symbol(scope, Decl(templateIndexedScopeOptions.ts, 0, 83)) +>options : Symbol(options, Decl(templateIndexedScopeOptions.ts, 2, 5)) + diff --git a/tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.types b/tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.types new file mode 100644 index 0000000000000..13851d4ca05f4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/templateIndexedScopeOptions.types @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/templateIndexedScopeOptions.ts] //// + +=== templateIndexedScopeOptions.ts === +type Attributes = { name?: string } & { [path: `$${string}.${string}$`]: unknown }; +>Attributes : Attributes +>name : string | undefined +>path : `$${string}.${string}$` + +declare function scope(options: Attributes | { method: readonly [string, ...unknown[]] }): void; +>scope : (options: Attributes | { method: readonly [string, ...unknown[]]; }) => void +>options : { method: readonly [string, ...unknown[]]; } | Attributes +>method : readonly [string, ...unknown[]] + +const options = { method: ["list", { id: 1 }] }; +>options : { method: (string | { id: number; })[]; } +>{ method: ["list", { id: 1 }] } : { method: (string | { id: number; })[]; } +>method : (string | { id: number; })[] +>["list", { id: 1 }] : (string | { id: number; })[] +>"list" : "list" +>{ id: 1 } : { id: number; } +>id : number +>1 : 1 + +scope(options); +>scope(options) : void +>scope : (options: Attributes | { method: readonly [string, ...unknown[]]; }) => void +>options : { method: (string | { id: number; })[]; } + diff --git a/tsc/testdata/tests/cases/compiler/templateIndexedScopeOptions.ts b/tsc/testdata/tests/cases/compiler/templateIndexedScopeOptions.ts new file mode 100644 index 0000000000000..49647f464b1f3 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/templateIndexedScopeOptions.ts @@ -0,0 +1,7 @@ +// @strict: true +// @noEmit: true + +type Attributes = { name?: string } & { [path: `$${string}.${string}$`]: unknown }; +declare function scope(options: Attributes | { method: readonly [string, ...unknown[]] }): void; +const options = { method: ["list", { id: 1 }] }; +scope(options); From 1d9ed7f60b053a0137f3f48e62fb0168eaa5193f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 15:53:05 -0700 Subject: [PATCH 032/116] Add historical coverage: inherited output directory root Exact original compiler APIs before0/head5011 for inherited outDir with no rootDir/local output key. Minimal config fixture asserts warning fallback at child compilerOptions and full emitted /project/dist/src/index.js path. Five actual source lines/inheritance chains read; tRPC relative configs pinned, Ky ^6.0.0 has unique published stable6.x config6.0.0 but no recovered bot install lock. Separate literal/configDir inherited controls preserve diagnostic source span. Existing generic output-root fixtures do not assert missing-local-option fallback. Does not claim coverage of326 missing native6059 boundary diagnostics. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62418#issuecomment-3572538432 Origin: https://redirect.github.com/microsoft/TypeScript/pull/62418#issuecomment-3572538397 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../inheritedOutputDirectoryRoot.errors.txt | 16 ++++++++++++++++ .../compiler/inheritedOutputDirectoryRoot.js | 11 +++++++++++ .../inheritedOutputDirectoryRoot.symbols | 6 ++++++ .../compiler/inheritedOutputDirectoryRoot.types | 7 +++++++ .../compiler/inheritedOutputDirectoryRoot.ts | 12 ++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.js create mode 100644 tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.types create mode 100644 tsc/testdata/tests/cases/compiler/inheritedOutputDirectoryRoot.ts diff --git a/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.errors.txt b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.errors.txt new file mode 100644 index 0000000000000..a31c8a87d1f13 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.errors.txt @@ -0,0 +1,16 @@ +/project/tsconfig.json(1,29): error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout. + Visit https://aka.ms/ts6 for migration information. + + +==== /project/tsconfig.json (1 errors) ==== + { "extends": "./base.json", "compilerOptions": {}, "files": ["src/index.ts"] } + ~~~~~~~~~~~~~~~~~ +!!! error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout. +!!! error TS5011: Visit https://aka.ms/ts6 for migration information. + +==== /project/src/index.ts (0 errors) ==== + export const value = 0; + +==== /project/base.json (0 errors) ==== + { "compilerOptions": { "outDir": "dist" } } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.js b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.js new file mode 100644 index 0000000000000..ccf7f864f655a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.js @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/inheritedOutputDirectoryRoot.ts] //// + +//// [base.json] +{ "compilerOptions": { "outDir": "dist" } } + +//// [index.ts] +export const value = 0; + + +//// [/project/dist/src/index.js] +export const value = 0; diff --git a/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.symbols b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.symbols new file mode 100644 index 0000000000000..af2340ff00ec8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.symbols @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/inheritedOutputDirectoryRoot.ts] //// + +=== /project/src/index.ts === +export const value = 0; +>value : Symbol(value, Decl(index.ts, 0, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.types b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.types new file mode 100644 index 0000000000000..5eb8aa142f544 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inheritedOutputDirectoryRoot.types @@ -0,0 +1,7 @@ +//// [tests/cases/compiler/inheritedOutputDirectoryRoot.ts] //// + +=== /project/src/index.ts === +export const value = 0; +>value : 0 +>0 : 0 + diff --git a/tsc/testdata/tests/cases/compiler/inheritedOutputDirectoryRoot.ts b/tsc/testdata/tests/cases/compiler/inheritedOutputDirectoryRoot.ts new file mode 100644 index 0000000000000..ed0a778fdfaee --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/inheritedOutputDirectoryRoot.ts @@ -0,0 +1,12 @@ +// @target: es2015 +// @noImplicitReferences: true +// @fullEmitPaths: true + +// @filename: /project/base.json +{ "compilerOptions": { "outDir": "dist" } } + +// @filename: /project/src/index.ts +export const value = 0; + +// @filename: /project/tsconfig.json +{ "extends": "./base.json", "compilerOptions": {}, "files": ["src/index.ts"] } From efbeb81aafc49d49092975e5d61da5fe9699b67b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 16:13:44 -0700 Subject: [PATCH 033/116] Add historical coverage: skipped circular matcher bases Exact original before0/head consumer2339 plus declaration2310x3/2339, native clean. Preserves Expect-before-Matchers ordering, merged base interfaces and unused generic ReturnType cycle; skipped declaration checking must retain inherited consumer method. Six exact Redux matcher AST sites with actual global setup augmentation, locked Vitest1.6.0/jest-dom6.5.0 and config chain; isolated @vitest/expect-only probe rejected because it omitted causal jest-dom augmentation. Actual dependency errors retained separately, no full Redux build or recovered bot binary claim. No external imports/copied declarations; skipLibCheck is required behavior, not masking. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60427#issuecomment-2460599689 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/skippedCircularMatcherBases.js | 18 ++++++++++ .../skippedCircularMatcherBases.symbols | 36 +++++++++++++++++++ .../skippedCircularMatcherBases.types | 26 ++++++++++++++ .../compiler/skippedCircularMatcherBases.ts | 14 ++++++++ 4 files changed, 94 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.js create mode 100644 tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.types create mode 100644 tsc/testdata/tests/cases/compiler/skippedCircularMatcherBases.ts diff --git a/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.js b/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.js new file mode 100644 index 0000000000000..375a104f9d327 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/skippedCircularMatcherBases.ts] //// + +//// [matchers.d.ts] +interface Expect extends Matchers {} +interface MatcherResult {} +interface Matchers { + containing(value: string): unknown; +} +interface Matchers extends MatcherResult> {} +declare const expect: Expect; + +//// [main.ts] +expect.containing("value"); + + +//// [main.js] +"use strict"; +expect.containing("value"); diff --git a/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.symbols b/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.symbols new file mode 100644 index 0000000000000..26a30f9b928e8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.symbols @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/skippedCircularMatcherBases.ts] //// + +=== matchers.d.ts === +interface Expect extends Matchers {} +>Expect : Symbol(Expect, Decl(matchers.d.ts, 0, 0)) +>Matchers : Symbol(Matchers, Decl(matchers.d.ts, 1, 34), Decl(matchers.d.ts, 4, 1)) + +interface MatcherResult {} +>MatcherResult : Symbol(MatcherResult, Decl(matchers.d.ts, 0, 36)) +>Result : Symbol(Result, Decl(matchers.d.ts, 1, 24)) + +interface Matchers { +>Matchers : Symbol(Matchers, Decl(matchers.d.ts, 1, 34), Decl(matchers.d.ts, 4, 1)) + + containing(value: string): unknown; +>containing : Symbol(Matchers.containing, Decl(matchers.d.ts, 2, 20)) +>value : Symbol(value, Decl(matchers.d.ts, 3, 15)) +} +interface Matchers extends MatcherResult> {} +>Matchers : Symbol(Matchers, Decl(matchers.d.ts, 1, 34), Decl(matchers.d.ts, 4, 1)) +>MatcherResult : Symbol(MatcherResult, Decl(matchers.d.ts, 0, 36)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>expect.containing : Symbol(Matchers.containing, Decl(matchers.d.ts, 2, 20)) +>expect : Symbol(expect, Decl(matchers.d.ts, 6, 13)) +>containing : Symbol(Matchers.containing, Decl(matchers.d.ts, 2, 20)) + +declare const expect: Expect; +>expect : Symbol(expect, Decl(matchers.d.ts, 6, 13)) +>Expect : Symbol(Expect, Decl(matchers.d.ts, 0, 0)) + +=== main.ts === +expect.containing("value"); +>expect.containing : Symbol(Matchers.containing, Decl(matchers.d.ts, 2, 20)) +>expect : Symbol(expect, Decl(matchers.d.ts, 6, 13)) +>containing : Symbol(Matchers.containing, Decl(matchers.d.ts, 2, 20)) + diff --git a/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.types b/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.types new file mode 100644 index 0000000000000..42094033fad85 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedCircularMatcherBases.types @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/skippedCircularMatcherBases.ts] //// + +=== matchers.d.ts === +interface Expect extends Matchers {} +interface MatcherResult {} +interface Matchers { + containing(value: string): unknown; +>containing : (value: string) => unknown +>value : string +} +interface Matchers extends MatcherResult> {} +>expect.containing : (value: string) => unknown +>expect : Expect +>containing : (value: string) => unknown + +declare const expect: Expect; +>expect : Expect + +=== main.ts === +expect.containing("value"); +>expect.containing("value") : unknown +>expect.containing : (value: string) => unknown +>expect : Expect +>containing : (value: string) => unknown +>"value" : "value" + diff --git a/tsc/testdata/tests/cases/compiler/skippedCircularMatcherBases.ts b/tsc/testdata/tests/cases/compiler/skippedCircularMatcherBases.ts new file mode 100644 index 0000000000000..6f4854ab51cd5 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/skippedCircularMatcherBases.ts @@ -0,0 +1,14 @@ +// @skipLibCheck: true +// @strict: true + +// @filename: matchers.d.ts +interface Expect extends Matchers {} +interface MatcherResult {} +interface Matchers { + containing(value: string): unknown; +} +interface Matchers extends MatcherResult> {} +declare const expect: Expect; + +// @filename: main.ts +expect.containing("value"); From 0456a0b87f90de143d5f3dee643c6bbd71be7c6e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 16:32:55 -0700 Subject: [PATCH 034/116] Add historical coverage: unknown after typeof early return Exact integrated fixture before0/first-report0/second-report three2345/final0/current0. Boolean early return followed by string/bigint/number helper arguments preserves experimental excluded-unknown-flow regression; independent positive guards miss it. Six pinned GraphQL AST calls and prior return guards read. Second-report-preceding head2b33b774 is chronology-selected, not a recovered bot binary or merge commit; shared current libraries and source-shaped structural APIs, no full downstream build. Existing unknown/control-flow/switch/typeof controls executed under original directives do not detect this consumer loss. No external imports or copied declarations. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5706132906 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/unknownAfterTypeofEarlyReturn.js | 26 +++++++++ .../unknownAfterTypeofEarlyReturn.symbols | 39 ++++++++++++++ .../unknownAfterTypeofEarlyReturn.types | 54 +++++++++++++++++++ .../compiler/unknownAfterTypeofEarlyReturn.ts | 12 +++++ 4 files changed, 131 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.js create mode 100644 tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.types create mode 100644 tsc/testdata/tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts diff --git a/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.js b/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.js new file mode 100644 index 0000000000000..a20fffed24340 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.js @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts] //// + +//// [unknownAfterTypeofEarlyReturn.ts] +declare function fromString(value: string): number; +declare function fromBigint(value: bigint): number; +declare function fromNumber(value: number): boolean; +function coerce(value: unknown) { + if (typeof value === "boolean") return value; + if (typeof value === "string") return fromString(value); + if (typeof value === "bigint") return fromBigint(value); + if (typeof value === "number") return fromNumber(value); +} + + +//// [unknownAfterTypeofEarlyReturn.js] +"use strict"; +function coerce(value) { + if (typeof value === "boolean") + return value; + if (typeof value === "string") + return fromString(value); + if (typeof value === "bigint") + return fromBigint(value); + if (typeof value === "number") + return fromNumber(value); +} diff --git a/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.symbols b/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.symbols new file mode 100644 index 0000000000000..b0bc1de980cd1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.symbols @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts] //// + +=== unknownAfterTypeofEarlyReturn.ts === +declare function fromString(value: string): number; +>fromString : Symbol(fromString, Decl(unknownAfterTypeofEarlyReturn.ts, 0, 0)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 0, 28)) + +declare function fromBigint(value: bigint): number; +>fromBigint : Symbol(fromBigint, Decl(unknownAfterTypeofEarlyReturn.ts, 0, 51)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 1, 28)) + +declare function fromNumber(value: number): boolean; +>fromNumber : Symbol(fromNumber, Decl(unknownAfterTypeofEarlyReturn.ts, 1, 51)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 2, 28)) + +function coerce(value: unknown) { +>coerce : Symbol(coerce, Decl(unknownAfterTypeofEarlyReturn.ts, 2, 52)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) + + if (typeof value === "boolean") return value; +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) + + if (typeof value === "string") return fromString(value); +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) +>fromString : Symbol(fromString, Decl(unknownAfterTypeofEarlyReturn.ts, 0, 0)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) + + if (typeof value === "bigint") return fromBigint(value); +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) +>fromBigint : Symbol(fromBigint, Decl(unknownAfterTypeofEarlyReturn.ts, 0, 51)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) + + if (typeof value === "number") return fromNumber(value); +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) +>fromNumber : Symbol(fromNumber, Decl(unknownAfterTypeofEarlyReturn.ts, 1, 51)) +>value : Symbol(value, Decl(unknownAfterTypeofEarlyReturn.ts, 3, 16)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.types b/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.types new file mode 100644 index 0000000000000..7609eaebb6a66 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unknownAfterTypeofEarlyReturn.types @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts] //// + +=== unknownAfterTypeofEarlyReturn.ts === +declare function fromString(value: string): number; +>fromString : (value: string) => number +>value : string + +declare function fromBigint(value: bigint): number; +>fromBigint : (value: bigint) => number +>value : bigint + +declare function fromNumber(value: number): boolean; +>fromNumber : (value: number) => boolean +>value : number + +function coerce(value: unknown) { +>coerce : (value: unknown) => number | boolean | undefined +>value : unknown + + if (typeof value === "boolean") return value; +>typeof value === "boolean" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"boolean" : "boolean" +>value : boolean + + if (typeof value === "string") return fromString(value); +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" +>fromString(value) : number +>fromString : (value: string) => number +>value : string + + if (typeof value === "bigint") return fromBigint(value); +>typeof value === "bigint" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"bigint" : "bigint" +>fromBigint(value) : number +>fromBigint : (value: bigint) => number +>value : bigint + + if (typeof value === "number") return fromNumber(value); +>typeof value === "number" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"number" : "number" +>fromNumber(value) : boolean +>fromNumber : (value: number) => boolean +>value : number +} + diff --git a/tsc/testdata/tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts b/tsc/testdata/tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts new file mode 100644 index 0000000000000..12735c004edf8 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/unknownAfterTypeofEarlyReturn.ts @@ -0,0 +1,12 @@ +// @target: es2021 +// @strict: true + +declare function fromString(value: string): number; +declare function fromBigint(value: bigint): number; +declare function fromNumber(value: number): boolean; +function coerce(value: unknown) { + if (typeof value === "boolean") return value; + if (typeof value === "string") return fromString(value); + if (typeof value === "bigint") return fromBigint(value); + if (typeof value === "number") return fromNumber(value); +} From f1072bb26d91d67929efef287f95d4c4361e3a1e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 16:32:59 -0700 Subject: [PATCH 035/116] Add historical coverage: literal union after excluded comparisons Exact integrated fixture before0/first-report2322/second-report0/final0/current0. Three excluded literal comparisons under conjunction then throw must narrow remaining string to Runtime. Exact pinned GraphQL benchmark AST assignment and guard read. Existing literalTypes3 detects related positive-OR inference loss but does not contain this negative-conjunction-after-throw form. First-report-preceding5660da11 selected by chronology, not recovered bot binary/merge artifact; shared current libraries, no full downstream build. Minimal self-contained regression. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565670 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../literalUnionAfterExcludedComparisons.js | 20 ++++++++++++ ...teralUnionAfterExcludedComparisons.symbols | 23 ++++++++++++++ ...literalUnionAfterExcludedComparisons.types | 31 +++++++++++++++++++ .../literalUnionAfterExcludedComparisons.ts | 10 ++++++ 4 files changed, 84 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.js create mode 100644 tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types create mode 100644 tsc/testdata/tests/cases/compiler/literalUnionAfterExcludedComparisons.ts diff --git a/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.js b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.js new file mode 100644 index 0000000000000..a1a7bcfecde1c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/literalUnionAfterExcludedComparisons.ts] //// + +//// [literalUnionAfterExcludedComparisons.ts] +type Runtime = "node" | "deno" | "bun"; +function readRuntime(value: string): Runtime { + if (value !== "node" && value !== "deno" && value !== "bun") { + throw new Error(); + } + return value; +} + + +//// [literalUnionAfterExcludedComparisons.js] +"use strict"; +function readRuntime(value) { + if (value !== "node" && value !== "deno" && value !== "bun") { + throw new Error(); + } + return value; +} diff --git a/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.symbols b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.symbols new file mode 100644 index 0000000000000..246ebe7f424ce --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/literalUnionAfterExcludedComparisons.ts] //// + +=== literalUnionAfterExcludedComparisons.ts === +type Runtime = "node" | "deno" | "bun"; +>Runtime : Symbol(Runtime, Decl(literalUnionAfterExcludedComparisons.ts, 0, 0)) + +function readRuntime(value: string): Runtime { +>readRuntime : Symbol(readRuntime, Decl(literalUnionAfterExcludedComparisons.ts, 0, 39)) +>value : Symbol(value, Decl(literalUnionAfterExcludedComparisons.ts, 1, 21)) +>Runtime : Symbol(Runtime, Decl(literalUnionAfterExcludedComparisons.ts, 0, 0)) + + if (value !== "node" && value !== "deno" && value !== "bun") { +>value : Symbol(value, Decl(literalUnionAfterExcludedComparisons.ts, 1, 21)) +>value : Symbol(value, Decl(literalUnionAfterExcludedComparisons.ts, 1, 21)) +>value : Symbol(value, Decl(literalUnionAfterExcludedComparisons.ts, 1, 21)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + return value; +>value : Symbol(value, Decl(literalUnionAfterExcludedComparisons.ts, 1, 21)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types new file mode 100644 index 0000000000000..4212f993a140d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/literalUnionAfterExcludedComparisons.ts] //// + +=== literalUnionAfterExcludedComparisons.ts === +type Runtime = "node" | "deno" | "bun"; +>Runtime : Runtime + +function readRuntime(value: string): Runtime { +>readRuntime : (value: string) => Runtime +>value : string + + if (value !== "node" && value !== "deno" && value !== "bun") { +>value !== "node" && value !== "deno" && value !== "bun" : boolean +>value !== "node" && value !== "deno" : boolean +>value !== "node" : boolean +>value : string +>"node" : "node" +>value !== "deno" : boolean +>value : string +>"deno" : "deno" +>value !== "bun" : boolean +>value : string +>"bun" : "bun" + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + } + return value; +>value : "bun" | "deno" | "node" +} + diff --git a/tsc/testdata/tests/cases/compiler/literalUnionAfterExcludedComparisons.ts b/tsc/testdata/tests/cases/compiler/literalUnionAfterExcludedComparisons.ts new file mode 100644 index 0000000000000..b10fc2d2f020a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/literalUnionAfterExcludedComparisons.ts @@ -0,0 +1,10 @@ +// @target: es2021 +// @strict: true + +type Runtime = "node" | "deno" | "bun"; +function readRuntime(value: string): Runtime { + if (value !== "node" && value !== "deno" && value !== "bun") { + throw new Error(); + } + return value; +} From 801f8d3248c41ef47443450809475f4ba789fd5a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 16:41:05 -0700 Subject: [PATCH 036/116] Add historical coverage: compound assignment after excluded literal Exact pinned Clack += AST and nonempty string-property guard read. Source-shaped full boolean conjunction and exact integrated five-line reduction before0/first-report2322/second-report0/final0/current0 with actual ES2022/Node16 checker context. Excluded string must not become compound-assignment destination contract. Existing literal widening, flow-property and empty-string-union controls executed with original checker directives remain diagnostic-clean and lack this guarded broad-string compound form. Shared current libraries; chronology-selected archived heads, not recovered exact bot binaries or full Clack build. No imports/dependencies/copied declarations. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565223 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compoundAssignmentAfterExcludedLiteral.js | 17 +++++++++++++ ...oundAssignmentAfterExcludedLiteral.symbols | 20 ++++++++++++++++ ...mpoundAssignmentAfterExcludedLiteral.types | 24 +++++++++++++++++++ .../compoundAssignmentAfterExcludedLiteral.ts | 7 ++++++ 4 files changed, 68 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.js create mode 100644 tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.types create mode 100644 tsc/testdata/tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts diff --git a/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.js b/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.js new file mode 100644 index 0000000000000..52c6f725d3381 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts] //// + +//// [compoundAssignmentAfterExcludedLiteral.ts] +function append(buffer: { value: string }) { + if (buffer.value !== "") { + buffer.value += "\n"; + } +} + + +//// [compoundAssignmentAfterExcludedLiteral.js] +"use strict"; +function append(buffer) { + if (buffer.value !== "") { + buffer.value += "\n"; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.symbols b/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.symbols new file mode 100644 index 0000000000000..472f64a2a0e46 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts] //// + +=== compoundAssignmentAfterExcludedLiteral.ts === +function append(buffer: { value: string }) { +>append : Symbol(append, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 0)) +>buffer : Symbol(buffer, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 16)) +>value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25)) + + if (buffer.value !== "") { +>buffer.value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25)) +>buffer : Symbol(buffer, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 16)) +>value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25)) + + buffer.value += "\n"; +>buffer.value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25)) +>buffer : Symbol(buffer, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 16)) +>value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.types b/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.types new file mode 100644 index 0000000000000..438dc95ed9274 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/compoundAssignmentAfterExcludedLiteral.types @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts] //// + +=== compoundAssignmentAfterExcludedLiteral.ts === +function append(buffer: { value: string }) { +>append : (buffer: { value: string; }) => void +>buffer : { value: string; } +>value : string + + if (buffer.value !== "") { +>buffer.value !== "" : boolean +>buffer.value : string +>buffer : { value: string; } +>value : string +>"" : "" + + buffer.value += "\n"; +>buffer.value += "\n" : string +>buffer.value : string +>buffer : { value: string; } +>value : string +>"\n" : "\n" + } +} + diff --git a/tsc/testdata/tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts b/tsc/testdata/tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts new file mode 100644 index 0000000000000..6916fe91344f0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts @@ -0,0 +1,7 @@ +// @strict: true + +function append(buffer: { value: string }) { + if (buffer.value !== "") { + buffer.value += "\n"; + } +} From 0b0ccea7aa07ab1e7fba5f6b6ac80a737711f713 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 16:51:00 -0700 Subject: [PATCH 037/116] Add historical coverage: excluded numeric literal after decrement Exact pinned Budibase openCount===0 site, numeric initializer and preceding zero guard/decrement AST verified. Agent full loop and exact five-line integrated reduction before0/first-report2367/second-report0/final0/current0. Mutation invalidates excluded-zero fact: count1 can become0. Existing typeof numeric-update controls retain original diagnostics, large union stress case remains2590 and is not exact coverage. No loop/parser boilerplate/imports/dependencies. Chronology-selected archived heads with shared current libraries, no recovered bot binary/full downstream build. Scratch close() DOM name collision rejected and renamed decrement. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565223 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../excludedNumericLiteralAfterDecrement.js | 19 ++++++++++++++++ ...cludedNumericLiteralAfterDecrement.symbols | 17 ++++++++++++++ ...excludedNumericLiteralAfterDecrement.types | 22 +++++++++++++++++++ .../excludedNumericLiteralAfterDecrement.ts | 7 ++++++ 4 files changed, 65 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.js create mode 100644 tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types create mode 100644 tsc/testdata/tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts diff --git a/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.js b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.js new file mode 100644 index 0000000000000..cfdd6a0491ed4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts] //// + +//// [excludedNumericLiteralAfterDecrement.ts] +function decrement(count: number) { + if (count === 0) return; + count--; + if (count === 0) return; +} + + +//// [excludedNumericLiteralAfterDecrement.js] +"use strict"; +function decrement(count) { + if (count === 0) + return; + count--; + if (count === 0) + return; +} diff --git a/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.symbols b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.symbols new file mode 100644 index 0000000000000..5cf5b75db2270 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts] //// + +=== excludedNumericLiteralAfterDecrement.ts === +function decrement(count: number) { +>decrement : Symbol(decrement, Decl(excludedNumericLiteralAfterDecrement.ts, 0, 0)) +>count : Symbol(count, Decl(excludedNumericLiteralAfterDecrement.ts, 0, 19)) + + if (count === 0) return; +>count : Symbol(count, Decl(excludedNumericLiteralAfterDecrement.ts, 0, 19)) + + count--; +>count : Symbol(count, Decl(excludedNumericLiteralAfterDecrement.ts, 0, 19)) + + if (count === 0) return; +>count : Symbol(count, Decl(excludedNumericLiteralAfterDecrement.ts, 0, 19)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types new file mode 100644 index 0000000000000..7a3d3f9e4ad78 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts] //// + +=== excludedNumericLiteralAfterDecrement.ts === +function decrement(count: number) { +>decrement : (count: number) => void +>count : number + + if (count === 0) return; +>count === 0 : boolean +>count : number +>0 : 0 + + count--; +>count-- : number +>count : number + + if (count === 0) return; +>count === 0 : boolean +>count : number +>0 : 0 +} + diff --git a/tsc/testdata/tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts b/tsc/testdata/tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts new file mode 100644 index 0000000000000..f2a0f7f09a4ef --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/excludedNumericLiteralAfterDecrement.ts @@ -0,0 +1,7 @@ +// @strict: true + +function decrement(count: number) { + if (count === 0) return; + count--; + if (count === 0) return; +} From 712d6eec3ba96b01d56083314abfa954b9c26fcd Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 16:51:04 -0700 Subject: [PATCH 038/116] Add historical coverage: redundant numeric literal comparison Exact pinned hooks pollingErrorRetryCount default-1/countRef useRef(0), redundant right-OR !==-1 AST and both reports verified. Full source-shaped and three-line integrated reduction before0/first-report2367/second-report2367/final2367/current0. RHS comparison is logically redundant; experimental diagnostic persists at final head, so NOT falsely called fixed-before-merge or necessarily a bug. Test characterizes currently accepted broad-number redundant comparison form lacking in existing typeof/union candidates; intentional negation policy would need acknowledged baseline change. Shared current libraries, chronology-selected heads not recovered bot binaries/full hooks build. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565223 Repeated: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5706132673 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../redundantNumericLiteralComparison.js | 13 ++++++++++ .../redundantNumericLiteralComparison.symbols | 15 +++++++++++ .../redundantNumericLiteralComparison.types | 25 +++++++++++++++++++ .../redundantNumericLiteralComparison.ts | 5 ++++ 4 files changed, 58 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.js create mode 100644 tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.types create mode 100644 tsc/testdata/tests/cases/compiler/redundantNumericLiteralComparison.ts diff --git a/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.js b/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.js new file mode 100644 index 0000000000000..f6b1af1ae9d45 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/redundantNumericLiteralComparison.ts] //// + +//// [redundantNumericLiteralComparison.ts] +function shouldRetry(retryCount: number, currentCount: number) { + return retryCount === -1 || (retryCount !== -1 && currentCount <= retryCount); +} + + +//// [redundantNumericLiteralComparison.js] +"use strict"; +function shouldRetry(retryCount, currentCount) { + return retryCount === -1 || (retryCount !== -1 && currentCount <= retryCount); +} diff --git a/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.symbols b/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.symbols new file mode 100644 index 0000000000000..87036e32f0fd4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/redundantNumericLiteralComparison.ts] //// + +=== redundantNumericLiteralComparison.ts === +function shouldRetry(retryCount: number, currentCount: number) { +>shouldRetry : Symbol(shouldRetry, Decl(redundantNumericLiteralComparison.ts, 0, 0)) +>retryCount : Symbol(retryCount, Decl(redundantNumericLiteralComparison.ts, 0, 21)) +>currentCount : Symbol(currentCount, Decl(redundantNumericLiteralComparison.ts, 0, 40)) + + return retryCount === -1 || (retryCount !== -1 && currentCount <= retryCount); +>retryCount : Symbol(retryCount, Decl(redundantNumericLiteralComparison.ts, 0, 21)) +>retryCount : Symbol(retryCount, Decl(redundantNumericLiteralComparison.ts, 0, 21)) +>currentCount : Symbol(currentCount, Decl(redundantNumericLiteralComparison.ts, 0, 40)) +>retryCount : Symbol(retryCount, Decl(redundantNumericLiteralComparison.ts, 0, 21)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.types b/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.types new file mode 100644 index 0000000000000..ca69d96fc529a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/redundantNumericLiteralComparison.types @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/redundantNumericLiteralComparison.ts] //// + +=== redundantNumericLiteralComparison.ts === +function shouldRetry(retryCount: number, currentCount: number) { +>shouldRetry : (retryCount: number, currentCount: number) => boolean +>retryCount : number +>currentCount : number + + return retryCount === -1 || (retryCount !== -1 && currentCount <= retryCount); +>retryCount === -1 || (retryCount !== -1 && currentCount <= retryCount) : boolean +>retryCount === -1 : boolean +>retryCount : number +>-1 : -1 +>1 : 1 +>(retryCount !== -1 && currentCount <= retryCount) : boolean +>retryCount !== -1 && currentCount <= retryCount : boolean +>retryCount !== -1 : boolean +>retryCount : number +>-1 : -1 +>1 : 1 +>currentCount <= retryCount : boolean +>currentCount : number +>retryCount : number +} + diff --git a/tsc/testdata/tests/cases/compiler/redundantNumericLiteralComparison.ts b/tsc/testdata/tests/cases/compiler/redundantNumericLiteralComparison.ts new file mode 100644 index 0000000000000..65662760ebd6a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/redundantNumericLiteralComparison.ts @@ -0,0 +1,5 @@ +// @strict: true + +function shouldRetry(retryCount: number, currentCount: number) { + return retryCount === -1 || (retryCount !== -1 && currentCount <= retryCount); +} From 98b2122d4bc988eeb1ae924e03a226c871e307c6 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 17:16:27 -0700 Subject: [PATCH 039/116] Add historical coverage: dynamic declaration default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two exact pinned VS Code destructured dynamic-import default ASTs; actual source-lock v8-inspect-profiler0.1.1 published named-only ambient declaration and actual tsec→src→base config chain. Real declaration source-shaped importer retains NodeNext/ES2024/esModuleInterop/allowSyntheticDefaultImports/strict/skipLibCheck, before0→head2339/currentJS0 scoped; configured missing ambient-package2688 retained separately, no full VS Code build or recovered bot-install claim. Exact integrated thirteen-line ambient declaration/mts fixture before0→2339/native0. Existing dynamic synthetic-default test is export=, not named-only ambient declaration; exact original system/bundler options have5071/5095 under historical compilers and are not falsely claimed clean. Nested imports have real explicit defaults; static import cases detect shared guard but not dynamic namespace synthesis. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62530#issuecomment-3362940170 Repeated: https://redirect.github.com/microsoft/TypeScript/pull/62530#issuecomment-3363596323 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/dynamicDeclarationDefault.js | 16 +++++++++++++ .../dynamicDeclarationDefault.symbols | 21 ++++++++++++++++ .../compiler/dynamicDeclarationDefault.types | 24 +++++++++++++++++++ .../compiler/dynamicDeclarationDefault.ts | 13 ++++++++++ 4 files changed, 74 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.js create mode 100644 tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.types create mode 100644 tsc/testdata/tests/cases/compiler/dynamicDeclarationDefault.ts diff --git a/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.js b/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.js new file mode 100644 index 0000000000000..bd4eaaad5a044 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/dynamicDeclarationDefault.ts] //// + +//// [profiler.d.ts] +declare module "profiler" { + export function start(): void; +} + +//// [main.mts] +const { default: profiler } = await import("profiler"); +profiler.start(); + + +//// [main.mjs] +const { default: profiler } = await import("profiler"); +profiler.start(); +export {}; diff --git a/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.symbols b/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.symbols new file mode 100644 index 0000000000000..f2a5b602c0c35 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/dynamicDeclarationDefault.ts] //// + +=== profiler.d.ts === +declare module "profiler" { +>"profiler" : Symbol("profiler", Decl(profiler.d.ts, 0, 0)) + + export function start(): void; +>start : Symbol(start, Decl(profiler.d.ts, 0, 27)) +} + +=== main.mts === +const { default: profiler } = await import("profiler"); +>default : Symbol(default) +>profiler : Symbol(profiler, Decl(main.mts, 0, 7)) +>"profiler" : Symbol("profiler", Decl(profiler.d.ts, 0, 0)) + +profiler.start(); +>profiler.start : Symbol(start, Decl(profiler.d.ts, 0, 27)) +>profiler : Symbol(profiler, Decl(main.mts, 0, 7)) +>start : Symbol(start, Decl(profiler.d.ts, 0, 27)) + diff --git a/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.types b/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.types new file mode 100644 index 0000000000000..fbffb73aea1a4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/dynamicDeclarationDefault.types @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/dynamicDeclarationDefault.ts] //// + +=== profiler.d.ts === +declare module "profiler" { +>"profiler" : typeof import("profiler") + + export function start(): void; +>start : () => void +} + +=== main.mts === +const { default: profiler } = await import("profiler"); +>default : any +>profiler : typeof import("profiler") +>await import("profiler") : { start(): void; default: typeof import("profiler"); } +>import("profiler") : Promise<{ start(): void; default: typeof import("profiler"); }> +>"profiler" : "profiler" + +profiler.start(); +>profiler.start() : void +>profiler.start : () => void +>profiler : typeof import("profiler") +>start : () => void + diff --git a/tsc/testdata/tests/cases/compiler/dynamicDeclarationDefault.ts b/tsc/testdata/tests/cases/compiler/dynamicDeclarationDefault.ts new file mode 100644 index 0000000000000..4db5af5428621 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/dynamicDeclarationDefault.ts @@ -0,0 +1,13 @@ +// @target: es2024 +// @module: nodenext +// @strict: true +// @esModuleInterop: true + +// @filename: profiler.d.ts +declare module "profiler" { + export function start(): void; +} + +// @filename: main.mts +const { default: profiler } = await import("profiler"); +profiler.start(); From d1aa7a42c9a2574ebf1e2bdc91d8e84e15be07d1 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 13 Oct 2026 17:16:31 -0700 Subject: [PATCH 040/116] Add historical coverage: skipped implicit handler parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exactly two ActualBudget handler(args) ASTs old0→head2345. Exact integrated skipLibCheck/strict:false/strictFunctionTypes:true declaration-order-sensitive generic Parameters[0] dispatcher old0→head2345/current native2345. REAL current-negative diagnostic/types/symbol baseline, NOT preserving historical clean acceptance or preventing that old break. Typed object/string declarations precede any save declaration, but save interface inherited first; explicit any keeps differential, homogeneous branches0 all snapshots, typed-first inheritance already2345 before. Allocation/order-dependent mixed callable intersection, not implicit-any identity. PR60427 closed unmerged experiment, intentionality of this callable break unconfirmed. Prior numeric/string/generic union controls lack inherited any arm and Parameters dispatcher. Actual source62→79 other missing-dependency errors retained; no full downstream build or implementation fix. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60427#issuecomment-2460598834 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...kippedImplicitHandlerParameters.errors.txt | 22 ++++++++++ .../skippedImplicitHandlerParameters.js | 23 ++++++++++ .../skippedImplicitHandlerParameters.symbols | 43 +++++++++++++++++++ .../skippedImplicitHandlerParameters.types | 31 +++++++++++++ .../skippedImplicitHandlerParameters.ts | 18 ++++++++ 5 files changed, 137 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.js create mode 100644 tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.types create mode 100644 tsc/testdata/tests/cases/compiler/skippedImplicitHandlerParameters.ts diff --git a/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.errors.txt b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.errors.txt new file mode 100644 index 0000000000000..1762af422c8c9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.errors.txt @@ -0,0 +1,22 @@ +main.ts(2,13): error TS2345: Argument of type 'Parameters[0]' is not assignable to parameter of type 'never'. + Type 'any' is not assignable to type 'never'. + + +==== handlers.d.ts (0 errors) ==== + interface FilterHandlers { + update: (value: object) => void; + remove: (value: string) => void; + } + interface ServerHandlers { + save: (value) => "saved"; + } + interface Handlers extends ServerHandlers, FilterHandlers {} + +==== main.ts (1 errors) ==== + function runHandler(handler: T, value: Parameters[0]) { + handler(value); + ~~~~~ +!!! error TS2345: Argument of type 'Parameters[0]' is not assignable to parameter of type 'never'. +!!! error TS2345: Type 'any' is not assignable to type 'never'. + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.js b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.js new file mode 100644 index 0000000000000..7758f3d1e9ce2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/skippedImplicitHandlerParameters.ts] //// + +//// [handlers.d.ts] +interface FilterHandlers { + update: (value: object) => void; + remove: (value: string) => void; +} +interface ServerHandlers { + save: (value) => "saved"; +} +interface Handlers extends ServerHandlers, FilterHandlers {} + +//// [main.ts] +function runHandler(handler: T, value: Parameters[0]) { + handler(value); +} + + +//// [main.js] +"use strict"; +function runHandler(handler, value) { + handler(value); +} diff --git a/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.symbols b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.symbols new file mode 100644 index 0000000000000..4c05441149e8b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.symbols @@ -0,0 +1,43 @@ +//// [tests/cases/compiler/skippedImplicitHandlerParameters.ts] //// + +=== handlers.d.ts === +interface FilterHandlers { +>FilterHandlers : Symbol(FilterHandlers, Decl(handlers.d.ts, 0, 0)) + + update: (value: object) => void; +>update : Symbol(FilterHandlers.update, Decl(handlers.d.ts, 0, 26)) +>value : Symbol(value, Decl(handlers.d.ts, 1, 13)) + + remove: (value: string) => void; +>remove : Symbol(FilterHandlers.remove, Decl(handlers.d.ts, 1, 36)) +>value : Symbol(value, Decl(handlers.d.ts, 2, 13)) +} +interface ServerHandlers { +>ServerHandlers : Symbol(ServerHandlers, Decl(handlers.d.ts, 3, 1)) + + save: (value) => "saved"; +>save : Symbol(ServerHandlers.save, Decl(handlers.d.ts, 4, 26)) +>value : Symbol(value, Decl(handlers.d.ts, 5, 11)) +} +interface Handlers extends ServerHandlers, FilterHandlers {} +>Handlers : Symbol(Handlers, Decl(handlers.d.ts, 6, 1)) +>ServerHandlers : Symbol(ServerHandlers, Decl(handlers.d.ts, 3, 1)) +>FilterHandlers : Symbol(FilterHandlers, Decl(handlers.d.ts, 0, 0)) + +=== main.ts === +function runHandler(handler: T, value: Parameters[0]) { +>runHandler : Symbol(runHandler, Decl(main.ts, 0, 0)) +>T : Symbol(T, Decl(main.ts, 0, 20)) +>Handlers : Symbol(Handlers, Decl(handlers.d.ts, 6, 1)) +>Handlers : Symbol(Handlers, Decl(handlers.d.ts, 6, 1)) +>handler : Symbol(handler, Decl(main.ts, 0, 56)) +>T : Symbol(T, Decl(main.ts, 0, 20)) +>value : Symbol(value, Decl(main.ts, 0, 67)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(main.ts, 0, 20)) + + handler(value); +>handler : Symbol(handler, Decl(main.ts, 0, 56)) +>value : Symbol(value, Decl(main.ts, 0, 67)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.types b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.types new file mode 100644 index 0000000000000..02ef9ffba65b6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/skippedImplicitHandlerParameters.types @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/skippedImplicitHandlerParameters.ts] //// + +=== handlers.d.ts === +interface FilterHandlers { + update: (value: object) => void; +>update : (value: object) => void +>value : object + + remove: (value: string) => void; +>remove : (value: string) => void +>value : string +} +interface ServerHandlers { + save: (value) => "saved"; +>save : (value: any) => "saved" +>value : any +} +interface Handlers extends ServerHandlers, FilterHandlers {} + +=== main.ts === +function runHandler(handler: T, value: Parameters[0]) { +>runHandler : (handler: T, value: Parameters[0]) => void +>handler : T +>value : Parameters[0] + + handler(value); +>handler(value) : void | "saved" +>handler : ((value: object) => void) | ((value: string) => void) | ((value: any) => "saved") +>value : Parameters[0] +} + diff --git a/tsc/testdata/tests/cases/compiler/skippedImplicitHandlerParameters.ts b/tsc/testdata/tests/cases/compiler/skippedImplicitHandlerParameters.ts new file mode 100644 index 0000000000000..9c3835ef078b9 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/skippedImplicitHandlerParameters.ts @@ -0,0 +1,18 @@ +// @skipLibCheck: true +// @strict: false +// @strictFunctionTypes: true + +// @filename: handlers.d.ts +interface FilterHandlers { + update: (value: object) => void; + remove: (value: string) => void; +} +interface ServerHandlers { + save: (value) => "saved"; +} +interface Handlers extends ServerHandlers, FilterHandlers {} + +// @filename: main.ts +function runHandler(handler: T, value: Parameters[0]) { + handler(value); +} From e64701116607e894708b354d04f1ea87b8f78498 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 11:31:05 -0700 Subject: [PATCH 041/116] Add historical coverage: numeric compound assignment after excluded zero Exactly four pinned Fabric easing /= sites, actual conditional TEasingFunction default-unknown scalar four-number signature/early-zero returns guarded. Four full original easing function bodies with exact contextual alias independently compiled: all-code0 at four compound-site lines before/second/final/current, four2322 first; unrelated missing normalize/elastic helper diagnostics remain raw and are NOT a full build. Actual same-conditional-alias contextual-arrow witness and exact six-line integrated explicit-param reduction also old0/first2322/second0/final0/current0. Same broad-number write destination after excluded-zero fact. ES2015/strict isolated diagnostic witness, not full original config/build. Chronology-selected PR heads with shared current libraries, not bot merge binaries. Other31 numeric source identities remain pending, including double-excluded0&2 embedded subtraction. Minimal six-line broad-number /= after early-zero return; existing string-property compound assignment catches related shared mechanism but not scalar numeric write destination. Prior arithmetic assignment/getter-setter division tests lack excluded-zero guard. No dependencies or implementation changes. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565670 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ericCompoundAssignmentAfterExcludedZero.js | 16 ++++++++++++++++ ...ompoundAssignmentAfterExcludedZero.symbols | 16 ++++++++++++++++ ...cCompoundAssignmentAfterExcludedZero.types | 19 +++++++++++++++++++ ...ericCompoundAssignmentAfterExcludedZero.ts | 6 ++++++ 4 files changed, 57 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.js new file mode 100644 index 0000000000000..571d9f44cdf95 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts] //// + +//// [numericCompoundAssignmentAfterExcludedZero.ts] +function divide(value: number, divisor: number) { + if (value === 0) return; + value /= divisor; +} + + +//// [numericCompoundAssignmentAfterExcludedZero.js] +"use strict"; +function divide(value, divisor) { + if (value === 0) + return; + value /= divisor; +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.symbols new file mode 100644 index 0000000000000..9c5935a807fdb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts] //// + +=== numericCompoundAssignmentAfterExcludedZero.ts === +function divide(value: number, divisor: number) { +>divide : Symbol(divide, Decl(numericCompoundAssignmentAfterExcludedZero.ts, 0, 0)) +>value : Symbol(value, Decl(numericCompoundAssignmentAfterExcludedZero.ts, 0, 16)) +>divisor : Symbol(divisor, Decl(numericCompoundAssignmentAfterExcludedZero.ts, 0, 30)) + + if (value === 0) return; +>value : Symbol(value, Decl(numericCompoundAssignmentAfterExcludedZero.ts, 0, 16)) + + value /= divisor; +>value : Symbol(value, Decl(numericCompoundAssignmentAfterExcludedZero.ts, 0, 16)) +>divisor : Symbol(divisor, Decl(numericCompoundAssignmentAfterExcludedZero.ts, 0, 30)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.types new file mode 100644 index 0000000000000..5839afcb5200a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterExcludedZero.types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts] //// + +=== numericCompoundAssignmentAfterExcludedZero.ts === +function divide(value: number, divisor: number) { +>divide : (value: number, divisor: number) => void +>value : number +>divisor : number + + if (value === 0) return; +>value === 0 : boolean +>value : number +>0 : 0 + + value /= divisor; +>value /= divisor : number +>value : number +>divisor : number +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts new file mode 100644 index 0000000000000..8fe28f3cb5c6f --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterExcludedZero.ts @@ -0,0 +1,6 @@ +// @strict: true + +function divide(value: number, divisor: number) { + if (value === 0) return; + value /= divisor; +} From ce821f40a5a3ae62f0d8b0e404194eded6f36451 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 11:31:09 -0700 Subject: [PATCH 042/116] Add historical coverage: missing types condition default sidecar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exact Gitdiagram Geist source AST/source-lock1.3.1 published manifest and full file inventory: types FIRST targets missing dist/index.d.ts; later default sans.js has existing sans.d.ts. Exact integrated self-contained package/subpath/types-target/default-sidecar fixture before0→initial2307→final18062/current native0; native trace explicitly fails types then succeeds default sidecar. Related existing import-first-JS/types-later fallback already catches shared PR changes but not this missing-types-target form. Null-block/typesVersions/selfname/tslib conditions inspected; their targets exist or null is intentionally terminal. Source flags independently retained; source-lock NOT recovered bot install; comparison1.4.2 not bot pin, no complete Gitdiagram build/external library. One PrimeNG tokens import isolated package witness same earlier-missing-types abort before0/initial2307/final18062, later importMJS/d.mts sidecar; out-of-repo source path aliases unavailable and erased, NOT exact bot filesystem/full PrimeNG build. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62310#issuecomment-3208602832 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...issingTypesConditionDefaultSidecar.symbols | 16 +++++++++++++ ...ingTypesConditionDefaultSidecar.trace.json | 23 +++++++++++++++++++ .../missingTypesConditionDefaultSidecar.types | 16 +++++++++++++ .../missingTypesConditionDefaultSidecar.ts | 22 ++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.trace.json create mode 100644 tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.types create mode 100644 tsc/testdata/tests/cases/compiler/missingTypesConditionDefaultSidecar.ts diff --git a/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.symbols b/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.symbols new file mode 100644 index 0000000000000..d045288fa9d70 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/missingTypesConditionDefaultSidecar.ts] //// + +=== node_modules/font/sans.d.ts === +export const font: { className: string }; +>font : Symbol(font, Decl(sans.d.ts, 0, 12)) +>className : Symbol(className, Decl(sans.d.ts, 0, 20)) + +=== main.ts === +import { font } from "font/sans"; +>font : Symbol(font, Decl(main.ts, 0, 8)) + +font.className; +>font.className : Symbol(className, Decl(sans.d.ts, 0, 20)) +>font : Symbol(font, Decl(main.ts, 0, 8)) +>className : Symbol(className, Decl(sans.d.ts, 0, 20)) + diff --git a/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.trace.json b/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.trace.json new file mode 100644 index 0000000000000..8b45d5582dd2d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.trace.json @@ -0,0 +1,23 @@ +======== Resolving module 'font/sans' from '/.src/main.ts'. ======== +Explicitly specified module resolution kind: 'Bundler'. +Resolving in CJS mode with conditions 'import', 'types'. +File '/.src/package.json' does not exist. +File '/package.json' does not exist. +Loading module 'font/sans' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON. +Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration. +Found 'package.json' at '/.src/node_modules/font/package.json'. +Entering conditional exports. +Matched 'exports' condition 'types'. +Using 'exports' subpath './sans' with target './missing.d.ts'. +File '/.src/node_modules/font/missing.d.ts' does not exist. +Failed to resolve under condition 'types'. +Matched 'exports' condition 'default'. +Using 'exports' subpath './sans' with target './sans.js'. +File name '/.src/node_modules/font/sans.js' has a '.js' extension - stripping it. +File '/.src/node_modules/font/sans.ts' does not exist. +File '/.src/node_modules/font/sans.tsx' does not exist. +File '/.src/node_modules/font/sans.d.ts' exists - use it as a name resolution result. +Resolved under condition 'default'. +Exiting conditional exports. +Resolving real path for '/.src/node_modules/font/sans.d.ts', result '/.src/node_modules/font/sans.d.ts'. +======== Module name 'font/sans' was successfully resolved to '/.src/node_modules/font/sans.d.ts'. ======== diff --git a/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.types b/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.types new file mode 100644 index 0000000000000..1faada1e11191 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/missingTypesConditionDefaultSidecar.types @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/missingTypesConditionDefaultSidecar.ts] //// + +=== node_modules/font/sans.d.ts === +export const font: { className: string }; +>font : { className: string; } +>className : string + +=== main.ts === +import { font } from "font/sans"; +>font : { className: string; } + +font.className; +>font.className : string +>font : { className: string; } +>className : string + diff --git a/tsc/testdata/tests/cases/compiler/missingTypesConditionDefaultSidecar.ts b/tsc/testdata/tests/cases/compiler/missingTypesConditionDefaultSidecar.ts new file mode 100644 index 0000000000000..479823ae1b74d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/missingTypesConditionDefaultSidecar.ts @@ -0,0 +1,22 @@ +// @module: esnext +// @moduleResolution: bundler +// @strict: true +// @traceResolution: true +// @noEmit: true + +// @filename: node_modules/font/package.json +{ + "exports": { + "./sans": { + "types": "./missing.d.ts", + "default": "./sans.js" + } + } +} + +// @filename: node_modules/font/sans.d.ts +export const font: { className: string }; + +// @filename: main.ts +import { font } from "font/sans"; +font.className; From 85198fff7f4eac1db654a13e25e77a3218d1c5df Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 11:38:31 -0700 Subject: [PATCH 043/116] Add historical coverage: default types exclude ambient module imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same genuine source-lock Node18.19.113/undici5.26.5 package present in BOTH omitted/explicit source trees. Exact full three source files and root module boundary; no external library copied into checked-in tests. Before genuinely binds52 export-from and2 imports through automatic Node ambient discovery. Source-config isolated program, not complete TypeDoc build. Report2307 versus executed2591 diagnostic substitution retained: exact archived source heads/current runtimes recognize missing Node declarations and suggest explicit types; NOT exact bot binaries or claim same diagnostic code. Explicit types restores same genuine Node declarations; omitted root files never directly include index.d.ts. Exact self-contained ambient declaration package fixture old0→after2307x2/current2307x2 when types omitted; explicit types runtime0 every compiler. Current-negative default-type-discovery compatibility characterization, not preserving historical clean acceptance. All54 genuine Node source sites independently executed using actualNode18 graph in evidence.json; reported2307 vs archived/current2591 explicitly retained. Prior addedglobal andlibrary-reference cases share default-types-discovery cause but not external ambient module specifier resolution. Existing import-vs-ambient case explicitly triple-slash roots ambient declarations; automatic directives/bundler cases use types:* or types:pkg; typingLookup uses explicit reference types, not omitted discovery. Initial implicit discovery wrongly used repository cwd (68Nodefiles), rejected evidence preserved; repaired configFilePath/currentDirectory guards ALLdeclarations to same-tree exactNode18 (59files). No implementation changes; current2307x2 baseline intentionally records omitted defaulttypes policy, not a clean compatibility preservation claim. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63054#issuecomment-3808836369 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...TypesExcludeAmbientModuleImports.errors.txt | 18 ++++++++++++++++++ ...ultTypesExcludeAmbientModuleImports.symbols | 9 +++++++++ ...faultTypesExcludeAmbientModuleImports.types | 10 ++++++++++ .../defaultTypesExcludeAmbientModuleImports.ts | 14 ++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.errors.txt b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.errors.txt new file mode 100644 index 0000000000000..0f24a5b5f7739 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.errors.txt @@ -0,0 +1,18 @@ +/main.mts(1,23): error TS2307: Cannot find module 'engine' or its corresponding type declarations. +/main.mts(2,35): error TS2307: Cannot find module 'engine' or its corresponding type declarations. + + +==== /main.mts (2 errors) ==== + import { value } from "engine"; + ~~~~~~~~ +!!! error TS2307: Cannot find module 'engine' or its corresponding type declarations. + export { default as engine } from "engine"; + ~~~~~~~~ +!!! error TS2307: Cannot find module 'engine' or its corresponding type declarations. + +==== /node_modules/@types/runtime/index.d.ts (0 errors) ==== + declare module "engine" { + export const value: number; + export default function read(): void; + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.symbols b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.symbols new file mode 100644 index 0000000000000..31adc13e21164 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.symbols @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts] //// + +=== /main.mts === +import { value } from "engine"; +>value : Symbol(value, Decl(main.mts, 0, 8)) + +export { default as engine } from "engine"; +>engine : Symbol(engine, Decl(main.mts, 1, 8)) + diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.types b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.types new file mode 100644 index 0000000000000..b1675f86581fa --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeAmbientModuleImports.types @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts] //// + +=== /main.mts === +import { value } from "engine"; +>value : any + +export { default as engine } from "engine"; +>default : any +>engine : any + diff --git a/tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts new file mode 100644 index 0000000000000..459c6a6c7e5a7 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts @@ -0,0 +1,14 @@ +// @module: nodenext +// @noEmit: true +// @noImplicitReferences: true +// @currentDirectory: / + +// @filename: /node_modules/@types/runtime/index.d.ts +declare module "engine" { + export const value: number; + export default function read(): void; +} + +// @filename: /main.mts +import { value } from "engine"; +export { default as engine } from "engine"; From 71704caa9b16a4036d7be825637b8e2c48e7e261 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 11:54:23 -0700 Subject: [PATCH 044/116] Add historical coverage: embedded numeric compound assignment after excluded literals Exactly one Fabric embedded t-=1 AST with reported destination number¬0¬2; full original easeInOutElastic body and actual conditional TEasingFunction independently compiled in division evidence, old0/first2322/second0/final0/native0 at exact embedded site. Seven unrelated missing normalization/elastic/constant symbols remain in raw source-shaped diagnostics, not complete Fabric build. New eight-line integrated test preserves early0-return, intervening division, early2-return, then subtraction embedded in Math.pow multiplication; exactold0/firsttwo2322/later0/native0. Earlier division has separate existing case41 mapping; this new source identity is not a blanket assignment of other numeric sites. Original scalar arrow contextual type becomes explicit numeric params; derivative/exponential normalization and runtimeelastic API erased. Chronology-selected native archived snapshots/shared current libraries, not bot binaries/full source-config build. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565670 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...CompoundAssignmentAfterExcludedLiterals.js | 21 ++++++++++ ...undAssignmentAfterExcludedLiterals.symbols | 25 ++++++++++++ ...poundAssignmentAfterExcludedLiterals.types | 40 +++++++++++++++++++ ...CompoundAssignmentAfterExcludedLiterals.ts | 8 ++++ 4 files changed, 94 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.js create mode 100644 tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types create mode 100644 tsc/testdata/tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts diff --git a/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.js b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.js new file mode 100644 index 0000000000000..7414734450b32 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts] //// + +//// [embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts] +function ease(value: number, divisor: number) { + if (value === 0) return 0; + value /= divisor; + if (value === 2) return 2; + return Math.pow(2, -10 * (value -= 1)); +} + + +//// [embeddedNumericCompoundAssignmentAfterExcludedLiterals.js] +"use strict"; +function ease(value, divisor) { + if (value === 0) + return 0; + value /= divisor; + if (value === 2) + return 2; + return Math.pow(2, -10 * (value -= 1)); +} diff --git a/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.symbols b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.symbols new file mode 100644 index 0000000000000..d09e75481c8fa --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.symbols @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts] //// + +=== embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts === +function ease(value: number, divisor: number) { +>ease : Symbol(ease, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 0)) +>value : Symbol(value, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 14)) +>divisor : Symbol(divisor, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 28)) + + if (value === 0) return 0; +>value : Symbol(value, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 14)) + + value /= divisor; +>value : Symbol(value, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 14)) +>divisor : Symbol(divisor, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 28)) + + if (value === 2) return 2; +>value : Symbol(value, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 14)) + + return Math.pow(2, -10 * (value -= 1)); +>Math.pow : Symbol(Math.pow, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2025.float16.d.ts, --, --) ... and 1 more) +>pow : Symbol(Math.pow, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts, 0, 14)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types new file mode 100644 index 0000000000000..4dc48c9f792e4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts] //// + +=== embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts === +function ease(value: number, divisor: number) { +>ease : (value: number, divisor: number) => number +>value : number +>divisor : number + + if (value === 0) return 0; +>value === 0 : boolean +>value : number +>0 : 0 +>0 : 0 + + value /= divisor; +>value /= divisor : number +>value : number +>divisor : number + + if (value === 2) return 2; +>value === 2 : boolean +>value : number +>2 : 2 +>2 : 2 + + return Math.pow(2, -10 * (value -= 1)); +>Math.pow(2, -10 * (value -= 1)) : number +>Math.pow : (x: number, y: number) => number +>Math : Math +>pow : (x: number, y: number) => number +>2 : 2 +>-10 * (value -= 1) : number +>-10 : -10 +>10 : 10 +>(value -= 1) : number +>value -= 1 : number +>value : number +>1 : 1 +} + diff --git a/tsc/testdata/tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts b/tsc/testdata/tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts new file mode 100644 index 0000000000000..00560737a2fb9 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.ts @@ -0,0 +1,8 @@ +// @strict: true + +function ease(value: number, divisor: number) { + if (value === 0) return 0; + value /= divisor; + if (value === 2) return 2; + return Math.pow(2, -10 * (value -= 1)); +} From e93baf545b8b56e9e142c58abb054860d23528f0 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 12:15:13 -0700 Subject: [PATCH 045/116] Add historical coverage: numeric compound assignment in while loop after excluded zero Six exact pinned Embla decrement sites: const firstIndex0, arithmetic lastIndex fixture.slideOffsets.length-1 guarantees broad number, let i=lastIndex and entire original while condition/body retained. Fixture array contents and nonasserting carousel/expect API declarations structurally projected, no any; not full Jest/Embla build. One exact pinned tldraw bitmap for-update site: original explicit number parameter, loop initializer/condition/full comma incrementor retained; unrelated generic MapNode/owner/API/body erased only in source-shaped for-header witness. Two minimal integrated tests independently execute actual reported2322 on first chronology-selected report snapshot, all clean before/later/current. Strict/ES2015 isolated diagnostic probes, not complete source configs/projects or recovered bot merge binaries; native snapshots share current libraries. No other numeric IDs mapped by these proofs. Prior checkout-local zero-exclusion while/for search had no existing direct form; prior early-return numeric mutation coverage shares writeback cause but not loop condition and comma-update fact propagation. This six-line testcase isolates while-condition writeback; exactly six Embla sites map to it. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565525 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...dAssignmentInWhileLoopAfterExcludedZero.js | 17 +++++++++++++++++ ...gnmentInWhileLoopAfterExcludedZero.symbols | 15 +++++++++++++++ ...signmentInWhileLoopAfterExcludedZero.types | 19 +++++++++++++++++++ ...dAssignmentInWhileLoopAfterExcludedZero.ts | 6 ++++++ 4 files changed, 57 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.js new file mode 100644 index 0000000000000..7ee895202aa64 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts] //// + +//// [numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts] +function rewind(index: number) { + while (index !== 0) { + index -= 1; + } +} + + +//// [numericCompoundAssignmentInWhileLoopAfterExcludedZero.js] +"use strict"; +function rewind(index) { + while (index !== 0) { + index -= 1; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.symbols new file mode 100644 index 0000000000000..4baad52f28f2a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts] //// + +=== numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts === +function rewind(index: number) { +>rewind : Symbol(rewind, Decl(numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts, 0, 0)) +>index : Symbol(index, Decl(numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts, 0, 16)) + + while (index !== 0) { +>index : Symbol(index, Decl(numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts, 0, 16)) + + index -= 1; +>index : Symbol(index, Decl(numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts, 0, 16)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.types new file mode 100644 index 0000000000000..0d78ee80086fb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts] //// + +=== numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts === +function rewind(index: number) { +>rewind : (index: number) => void +>index : number + + while (index !== 0) { +>index !== 0 : boolean +>index : number +>0 : 0 + + index -= 1; +>index -= 1 : number +>index : number +>1 : 1 + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts new file mode 100644 index 0000000000000..3b49f9fc55d7e --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInWhileLoopAfterExcludedZero.ts @@ -0,0 +1,6 @@ +// @strict: true +function rewind(index: number) { + while (index !== 0) { + index -= 1; + } +} From 2f401c901c3cc044284abdf907956448644723a4 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 12:15:17 -0700 Subject: [PATCH 046/116] Add historical coverage: numeric compound assignment in for update after excluded zero Six exact pinned Embla decrement sites: const firstIndex0, arithmetic lastIndex fixture.slideOffsets.length-1 guarantees broad number, let i=lastIndex and entire original while condition/body retained. Fixture array contents and nonasserting carousel/expect API declarations structurally projected, no any; not full Jest/Embla build. One exact pinned tldraw bitmap for-update site: original explicit number parameter, loop initializer/condition/full comma incrementor retained; unrelated generic MapNode/owner/API/body erased only in source-shaped for-header witness. Two minimal integrated tests independently execute actual reported2322 on first chronology-selected report snapshot, all clean before/later/current. Strict/ES2015 isolated diagnostic probes, not complete source configs/projects or recovered bot merge binaries; native snapshots share current libraries. No other numeric IDs mapped by these proofs. Prior checkout-local zero-exclusion while/for search had no existing direct form; prior early-return numeric mutation coverage shares writeback cause but not loop condition and comma-update fact propagation. This four-line testcase isolates zero-excluded bitmap unsigned-shift writeback in a for-loop comma update; only dfc1ae42695e9b9e maps to it. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566504 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...dAssignmentInForUpdateAfterExcludedZero.js | 13 ++++++++++++ ...gnmentInForUpdateAfterExcludedZero.symbols | 14 +++++++++++++ ...signmentInForUpdateAfterExcludedZero.types | 21 +++++++++++++++++++ ...dAssignmentInForUpdateAfterExcludedZero.ts | 4 ++++ 4 files changed, 52 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.js new file mode 100644 index 0000000000000..c489c6bb3b445 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts] //// + +//// [numericCompoundAssignmentInForUpdateAfterExcludedZero.ts] +function shift(bitmap: number) { + for (let index = 0; bitmap !== 0; index++, bitmap >>>= 1) {} +} + + +//// [numericCompoundAssignmentInForUpdateAfterExcludedZero.js] +"use strict"; +function shift(bitmap) { + for (let index = 0; bitmap !== 0; index++, bitmap >>>= 1) { } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.symbols new file mode 100644 index 0000000000000..1998f2601e44c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.symbols @@ -0,0 +1,14 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts] //// + +=== numericCompoundAssignmentInForUpdateAfterExcludedZero.ts === +function shift(bitmap: number) { +>shift : Symbol(shift, Decl(numericCompoundAssignmentInForUpdateAfterExcludedZero.ts, 0, 0)) +>bitmap : Symbol(bitmap, Decl(numericCompoundAssignmentInForUpdateAfterExcludedZero.ts, 0, 15)) + + for (let index = 0; bitmap !== 0; index++, bitmap >>>= 1) {} +>index : Symbol(index, Decl(numericCompoundAssignmentInForUpdateAfterExcludedZero.ts, 1, 12)) +>bitmap : Symbol(bitmap, Decl(numericCompoundAssignmentInForUpdateAfterExcludedZero.ts, 0, 15)) +>index : Symbol(index, Decl(numericCompoundAssignmentInForUpdateAfterExcludedZero.ts, 1, 12)) +>bitmap : Symbol(bitmap, Decl(numericCompoundAssignmentInForUpdateAfterExcludedZero.ts, 0, 15)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.types new file mode 100644 index 0000000000000..4af6920adb6bb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.types @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts] //// + +=== numericCompoundAssignmentInForUpdateAfterExcludedZero.ts === +function shift(bitmap: number) { +>shift : (bitmap: number) => void +>bitmap : number + + for (let index = 0; bitmap !== 0; index++, bitmap >>>= 1) {} +>index : number +>0 : 0 +>bitmap !== 0 : boolean +>bitmap : number +>0 : 0 +>index++, bitmap >>>= 1 : number +>index++ : number +>index : number +>bitmap >>>= 1 : number +>bitmap : number +>1 : 1 +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts new file mode 100644 index 0000000000000..114e5cd984f3a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInForUpdateAfterExcludedZero.ts @@ -0,0 +1,4 @@ +// @strict: true +function shift(bitmap: number) { + for (let index = 0; bitmap !== 0; index++, bitmap >>>= 1) {} +} From ed45d507afc3d07db1bf86befe72ef850d5bd305 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 12:40:55 -0700 Subject: [PATCH 047/116] Add historical coverage: identity of instantiated mapped intersection Closed/unmerged intersection-identity experiment merges plain-object intersections but leaves instantiated mapped intersections unmerged, producing asymmetric identity normalization and false where the original equality assertion returned true. Original full test plus genuine SDK reproduces exactly the reported line19 diagnostic. Faithful sixteen-line reduction preserves required/optional/unknown maps and symbol-brand mapping; successively removing optional helpers, the optional-unknown intersection, and the brand mapping preserves the same exact differential. The final eight-line case retains the essential instantiated homomorphic map, intersection, unique-symbol brand and generic conditional identity assertion. Exact PR base/head with their separate original standard libraries; not recovered bot merge binaries. Source config inheritance and semantic flags retained; child only overrides output, which is disabled. Entire original test plus pinned real SDK, with only Jest ambient scaffold and types[] isolation; not full Zod/Jest build. Test-only characterization of an abandoned regression, not a merged implementation fix. Earlier agent's dated-npm/no-flatten/improvement conclusion rejected; global ignored-old-project counts do not determine this site's direction. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60726#issuecomment-2539759897 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...dentityOfInstantiatedMappedIntersection.js | 15 ++++++ ...tyOfInstantiatedMappedIntersection.symbols | 50 +++++++++++++++++++ ...tityOfInstantiatedMappedIntersection.types | 36 +++++++++++++ ...dentityOfInstantiatedMappedIntersection.ts | 8 +++ 4 files changed, 109 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.js create mode 100644 tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.types create mode 100644 tsc/testdata/tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts diff --git a/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.js b/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.js new file mode 100644 index 0000000000000..26394af1edfe4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts] //// + +//// [identityOfInstantiatedMappedIntersection.ts] +declare const brand: unique symbol; +type Equal = (() => V extends T ? 1 : 2) extends (() => V extends U ? 1 : 2) ? true : false; +declare function assertEqual(value: Equal): void; + +type Flatten = { [K in keyof T]: T[K] }; +type Branded = Flatten<{ name: string }> & { [brand]: { label: true } }; +assertEqual(true); + + +//// [identityOfInstantiatedMappedIntersection.js] +"use strict"; +assertEqual(true); diff --git a/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.symbols b/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.symbols new file mode 100644 index 0000000000000..b3a19b1982e83 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.symbols @@ -0,0 +1,50 @@ +//// [tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts] //// + +=== identityOfInstantiatedMappedIntersection.ts === +declare const brand: unique symbol; +>brand : Symbol(brand, Decl(identityOfInstantiatedMappedIntersection.ts, 0, 13)) + +type Equal = (() => V extends T ? 1 : 2) extends (() => V extends U ? 1 : 2) ? true : false; +>Equal : Symbol(Equal, Decl(identityOfInstantiatedMappedIntersection.ts, 0, 35)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 11)) +>U : Symbol(U, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 13)) +>V : Symbol(V, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 21)) +>V : Symbol(V, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 21)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 11)) +>V : Symbol(V, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 60)) +>V : Symbol(V, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 60)) +>U : Symbol(U, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 13)) + +declare function assertEqual(value: Equal): void; +>assertEqual : Symbol(assertEqual, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 104)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 29)) +>U : Symbol(U, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 31)) +>value : Symbol(value, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 35)) +>Equal : Symbol(Equal, Decl(identityOfInstantiatedMappedIntersection.ts, 0, 35)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 29)) +>U : Symbol(U, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 31)) + +type Flatten = { [K in keyof T]: T[K] }; +>Flatten : Symbol(Flatten, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 61)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 13)) +>K : Symbol(K, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 21)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 13)) +>T : Symbol(T, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 13)) +>K : Symbol(K, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 21)) + +type Branded = Flatten<{ name: string }> & { [brand]: { label: true } }; +>Branded : Symbol(Branded, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 43)) +>Flatten : Symbol(Flatten, Decl(identityOfInstantiatedMappedIntersection.ts, 2, 61)) +>name : Symbol(name, Decl(identityOfInstantiatedMappedIntersection.ts, 5, 24)) +>[brand] : Symbol([brand], Decl(identityOfInstantiatedMappedIntersection.ts, 5, 44)) +>brand : Symbol(brand, Decl(identityOfInstantiatedMappedIntersection.ts, 0, 13)) +>label : Symbol(label, Decl(identityOfInstantiatedMappedIntersection.ts, 5, 55)) + +assertEqual(true); +>assertEqual : Symbol(assertEqual, Decl(identityOfInstantiatedMappedIntersection.ts, 1, 104)) +>Branded : Symbol(Branded, Decl(identityOfInstantiatedMappedIntersection.ts, 4, 43)) +>name : Symbol(name, Decl(identityOfInstantiatedMappedIntersection.ts, 6, 22)) +>[brand] : Symbol([brand], Decl(identityOfInstantiatedMappedIntersection.ts, 6, 41)) +>brand : Symbol(brand, Decl(identityOfInstantiatedMappedIntersection.ts, 0, 13)) +>label : Symbol(label, Decl(identityOfInstantiatedMappedIntersection.ts, 6, 52)) + diff --git a/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.types b/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.types new file mode 100644 index 0000000000000..51697776612a5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/identityOfInstantiatedMappedIntersection.types @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts] //// + +=== identityOfInstantiatedMappedIntersection.ts === +declare const brand: unique symbol; +>brand : unique symbol + +type Equal = (() => V extends T ? 1 : 2) extends (() => V extends U ? 1 : 2) ? true : false; +>Equal : Equal +>true : true +>false : false + +declare function assertEqual(value: Equal): void; +>assertEqual : (value: Equal) => void +>value : Equal + +type Flatten = { [K in keyof T]: T[K] }; +>Flatten : Flatten + +type Branded = Flatten<{ name: string }> & { [brand]: { label: true } }; +>Branded : Branded +>name : string +>[brand] : { label: true; } +>brand : unique symbol +>label : true +>true : true + +assertEqual(true); +>assertEqual(true) : void +>assertEqual : (value: Equal) => void +>name : string +>[brand] : { label: true; } +>brand : unique symbol +>label : true +>true : true +>true : true + diff --git a/tsc/testdata/tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts b/tsc/testdata/tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts new file mode 100644 index 0000000000000..6c4f75b4cfeb0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/identityOfInstantiatedMappedIntersection.ts @@ -0,0 +1,8 @@ +// @strict: true +declare const brand: unique symbol; +type Equal = (() => V extends T ? 1 : 2) extends (() => V extends U ? 1 : 2) ? true : false; +declare function assertEqual(value: Equal): void; + +type Flatten = { [K in keyof T]: T[K] }; +type Branded = Flatten<{ name: string }> & { [brand]: { label: true } }; +assertEqual(true); From a6c2f14e1a3faef39aaaa3dc87aec6300e2dbd8b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:02:56 -0700 Subject: [PATCH 048/116] Add historical coverage: numeric compound assignment in else branch Exactly two pinned Fabric branches: original zero-initialized local, for header, complete positive/negative branch and charBox array assignment retained. Real GraphemeBBox width/kernedWidth:number and FabricText __charBounds:GraphemeBBox[][] guarded. SVG's explicit TextSVGExportMixin & FabricText receiver and actual ./Text import prove the field route; Text's Required assertion preserved. Structural FabricText only supplies accessed bounds/direction/text-lines; mixin runtime is erased. Text's line:Array is projected to its only-used length:number, not an any target or copied SDK. Rendering/style/path/state/return runtime omitted; not full functions/configs/project builds. Minimal eight-line branch-only witness independently retains positive and negative numeric += assignments. Exact diagnostic difference0/first2322/later0/current0 against chronology-selected heads/shared current libraries, not recovered bot merge binaries. No other identities mapped. Checkout-local exact-zero-condition and compound prior-art search finds no matching numeric else writeback; existing early-return and while/for tests share the cause but not this positive/negative branch form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688565670 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../numericCompoundAssignmentInElseBranch.js | 22 +++++++++++++++ ...ericCompoundAssignmentInElseBranch.symbols | 23 ++++++++++++++++ ...umericCompoundAssignmentInElseBranch.types | 27 +++++++++++++++++++ .../numericCompoundAssignmentInElseBranch.ts | 8 ++++++ 4 files changed, 80 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.js new file mode 100644 index 0000000000000..714ae8098d3f3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.js @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts] //// + +//// [numericCompoundAssignmentInElseBranch.ts] +function accumulate(total: number, width: number, kernedWidth: number) { + if (total === 0) { + total += width; + } else { + total += kernedWidth; + } +} + + +//// [numericCompoundAssignmentInElseBranch.js] +"use strict"; +function accumulate(total, width, kernedWidth) { + if (total === 0) { + total += width; + } + else { + total += kernedWidth; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.symbols new file mode 100644 index 0000000000000..070cfb4d57fb1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts] //// + +=== numericCompoundAssignmentInElseBranch.ts === +function accumulate(total: number, width: number, kernedWidth: number) { +>accumulate : Symbol(accumulate, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 0)) +>total : Symbol(total, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 20)) +>width : Symbol(width, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 34)) +>kernedWidth : Symbol(kernedWidth, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 49)) + + if (total === 0) { +>total : Symbol(total, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 20)) + + total += width; +>total : Symbol(total, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 20)) +>width : Symbol(width, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 34)) + + } else { + total += kernedWidth; +>total : Symbol(total, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 20)) +>kernedWidth : Symbol(kernedWidth, Decl(numericCompoundAssignmentInElseBranch.ts, 0, 49)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.types new file mode 100644 index 0000000000000..e0bf5042fdc9e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInElseBranch.types @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts] //// + +=== numericCompoundAssignmentInElseBranch.ts === +function accumulate(total: number, width: number, kernedWidth: number) { +>accumulate : (total: number, width: number, kernedWidth: number) => void +>total : number +>width : number +>kernedWidth : number + + if (total === 0) { +>total === 0 : boolean +>total : number +>0 : 0 + + total += width; +>total += width : number +>total : number +>width : number + + } else { + total += kernedWidth; +>total += kernedWidth : number +>total : number +>kernedWidth : number + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts new file mode 100644 index 0000000000000..b10fc71e686d1 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInElseBranch.ts @@ -0,0 +1,8 @@ +// @strict: true +function accumulate(total: number, width: number, kernedWidth: number) { + if (total === 0) { + total += width; + } else { + total += kernedWidth; + } +} From b82cc4b85375feeffe7f2b267c2e4e0c98c6e2e2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:32:10 -0700 Subject: [PATCH 049/116] Add historical coverage: numeric compound assignment after break Seven pinned Orca assignments guarded against original source AST/lines. Low-cost agent extracted numeric initialization and full relevant loops/callback/disjunction; independently executed source-shaped witness retains original findIndex/Math.max route and DOM query, captured Math.min producer/init-before-subscription order and actual nullable disposable result, both sequential toEvict break loops/status and negative-Set guards, tool-call/result depth assignments and positive else-if, full index/slice/continue/optional-push route, actual this numeric field and Math.min/Math.max/discard route with real numeric getter/void signature. Item/status/message structures supply only used fields/discriminants; unused message reset/interruption details, prompt/parser bodies, terminal implementation/payload/API presence, actual cap constant value, buffer storage/constructor/runtime and final record construction are explicitly projected. Terminal onData uses a callable surface with optionality for the preserved typeof guard, not a recovered xterm SDK graph; parseToolInput uses unknown only for unused prompt payload, never a numeric operand. No full functions/configs/projects/bot builds claimed. Historical matrices use strict ES2015 probes/chronology-selected heads/shared current libraries, not recovered bot merge binaries. Four new distinct break/continue/captured-callback/this-disjunction minimal forms plus existing early-return and positive/negative branch controls all independently give before0/first2322/later0/current0, with individual mutation lines and exact message guarded. Initial agent subscription-before-initialization and undefined-return projections were rejected/repaired before execution. Exact linked IDs: 95dfab9c918be95b, f229ec46c0e707f5. This independent minimal testcase preserves numeric compound assignment after break; existing early-return/while/for/else cases share the root but not this control-flow form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566356 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../numericCompoundAssignmentAfterBreak.js | 20 +++++++++++++++++++ ...umericCompoundAssignmentAfterBreak.symbols | 16 +++++++++++++++ .../numericCompoundAssignmentAfterBreak.types | 20 +++++++++++++++++++ .../numericCompoundAssignmentAfterBreak.ts | 7 +++++++ 4 files changed, 63 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.js new file mode 100644 index 0000000000000..502b5fdc3f07a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts] //// + +//// [numericCompoundAssignmentAfterBreak.ts] +function drain(count: number) { + for (;;) { + if (count === 0) break; + count -= 1; + } +} + + +//// [numericCompoundAssignmentAfterBreak.js] +"use strict"; +function drain(count) { + for (;;) { + if (count === 0) + break; + count -= 1; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.symbols new file mode 100644 index 0000000000000..04bea4239ddd5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts] //// + +=== numericCompoundAssignmentAfterBreak.ts === +function drain(count: number) { +>drain : Symbol(drain, Decl(numericCompoundAssignmentAfterBreak.ts, 0, 0)) +>count : Symbol(count, Decl(numericCompoundAssignmentAfterBreak.ts, 0, 15)) + + for (;;) { + if (count === 0) break; +>count : Symbol(count, Decl(numericCompoundAssignmentAfterBreak.ts, 0, 15)) + + count -= 1; +>count : Symbol(count, Decl(numericCompoundAssignmentAfterBreak.ts, 0, 15)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.types new file mode 100644 index 0000000000000..c0b8aa98bba1f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterBreak.types @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts] //// + +=== numericCompoundAssignmentAfterBreak.ts === +function drain(count: number) { +>drain : (count: number) => void +>count : number + + for (;;) { + if (count === 0) break; +>count === 0 : boolean +>count : number +>0 : 0 + + count -= 1; +>count -= 1 : number +>count : number +>1 : 1 + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts new file mode 100644 index 0000000000000..7ea4a2c1c0077 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterBreak.ts @@ -0,0 +1,7 @@ +// @strict: true +function drain(count: number) { + for (;;) { + if (count === 0) break; + count -= 1; + } +} From 8d034fdf1e15d8ad1a7712e2312f8693979e3877 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:32:14 -0700 Subject: [PATCH 050/116] Add historical coverage: numeric compound assignment after continue Seven pinned Orca assignments guarded against original source AST/lines. Low-cost agent extracted numeric initialization and full relevant loops/callback/disjunction; independently executed source-shaped witness retains original findIndex/Math.max route and DOM query, captured Math.min producer/init-before-subscription order and actual nullable disposable result, both sequential toEvict break loops/status and negative-Set guards, tool-call/result depth assignments and positive else-if, full index/slice/continue/optional-push route, actual this numeric field and Math.min/Math.max/discard route with real numeric getter/void signature. Item/status/message structures supply only used fields/discriminants; unused message reset/interruption details, prompt/parser bodies, terminal implementation/payload/API presence, actual cap constant value, buffer storage/constructor/runtime and final record construction are explicitly projected. Terminal onData uses a callable surface with optionality for the preserved typeof guard, not a recovered xterm SDK graph; parseToolInput uses unknown only for unused prompt payload, never a numeric operand. No full functions/configs/projects/bot builds claimed. Historical matrices use strict ES2015 probes/chronology-selected heads/shared current libraries, not recovered bot merge binaries. Four new distinct break/continue/captured-callback/this-disjunction minimal forms plus existing early-return and positive/negative branch controls all independently give before0/first2322/later0/current0, with individual mutation lines and exact message guarded. Initial agent subscription-before-initialization and undefined-return projections were rejected/repaired before execution. Exact linked IDs: e0002b123941c8c8. This independent minimal testcase preserves numeric compound assignment after continue; existing early-return/while/for/else cases share the root but not this control-flow form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566356 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../numericCompoundAssignmentAfterContinue.js | 20 +++++++++++++++++++ ...ricCompoundAssignmentAfterContinue.symbols | 16 +++++++++++++++ ...mericCompoundAssignmentAfterContinue.types | 20 +++++++++++++++++++ .../numericCompoundAssignmentAfterContinue.ts | 7 +++++++ 4 files changed, 63 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.js new file mode 100644 index 0000000000000..e6efa37e29b75 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts] //// + +//// [numericCompoundAssignmentAfterContinue.ts] +function consume(count: number) { + for (;;) { + if (count === 0) continue; + count -= 1; + } +} + + +//// [numericCompoundAssignmentAfterContinue.js] +"use strict"; +function consume(count) { + for (;;) { + if (count === 0) + continue; + count -= 1; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.symbols new file mode 100644 index 0000000000000..a5c831415ca2e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts] //// + +=== numericCompoundAssignmentAfterContinue.ts === +function consume(count: number) { +>consume : Symbol(consume, Decl(numericCompoundAssignmentAfterContinue.ts, 0, 0)) +>count : Symbol(count, Decl(numericCompoundAssignmentAfterContinue.ts, 0, 17)) + + for (;;) { + if (count === 0) continue; +>count : Symbol(count, Decl(numericCompoundAssignmentAfterContinue.ts, 0, 17)) + + count -= 1; +>count : Symbol(count, Decl(numericCompoundAssignmentAfterContinue.ts, 0, 17)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.types new file mode 100644 index 0000000000000..09a513c161e98 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentAfterContinue.types @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts] //// + +=== numericCompoundAssignmentAfterContinue.ts === +function consume(count: number) { +>consume : (count: number) => void +>count : number + + for (;;) { + if (count === 0) continue; +>count === 0 : boolean +>count : number +>0 : 0 + + count -= 1; +>count -= 1 : number +>count : number +>1 : 1 + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts new file mode 100644 index 0000000000000..972949d796081 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentAfterContinue.ts @@ -0,0 +1,7 @@ +// @strict: true +function consume(count: number) { + for (;;) { + if (count === 0) continue; + count -= 1; + } +} From a3f1f154c46a93e79abba289264bc91e44dd1e7c Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:32:17 -0700 Subject: [PATCH 051/116] Add historical coverage: numeric compound assignment in callback Seven pinned Orca assignments guarded against original source AST/lines. Low-cost agent extracted numeric initialization and full relevant loops/callback/disjunction; independently executed source-shaped witness retains original findIndex/Math.max route and DOM query, captured Math.min producer/init-before-subscription order and actual nullable disposable result, both sequential toEvict break loops/status and negative-Set guards, tool-call/result depth assignments and positive else-if, full index/slice/continue/optional-push route, actual this numeric field and Math.min/Math.max/discard route with real numeric getter/void signature. Item/status/message structures supply only used fields/discriminants; unused message reset/interruption details, prompt/parser bodies, terminal implementation/payload/API presence, actual cap constant value, buffer storage/constructor/runtime and final record construction are explicitly projected. Terminal onData uses a callable surface with optionality for the preserved typeof guard, not a recovered xterm SDK graph; parseToolInput uses unknown only for unused prompt payload, never a numeric operand. No full functions/configs/projects/bot builds claimed. Historical matrices use strict ES2015 probes/chronology-selected heads/shared current libraries, not recovered bot merge binaries. Four new distinct break/continue/captured-callback/this-disjunction minimal forms plus existing early-return and positive/negative branch controls all independently give before0/first2322/later0/current0, with individual mutation lines and exact message guarded. Initial agent subscription-before-initialization and undefined-return projections were rejected/repaired before execution. Exact linked IDs: 6b636a3391501338. This independent minimal testcase preserves numeric compound assignment in callback; existing early-return/while/for/else cases share the root but not this control-flow form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566356 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../numericCompoundAssignmentInCallback.js | 20 ++++++++++++++++ ...umericCompoundAssignmentInCallback.symbols | 17 ++++++++++++++ .../numericCompoundAssignmentInCallback.types | 23 +++++++++++++++++++ .../numericCompoundAssignmentInCallback.ts | 7 ++++++ 4 files changed, 67 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInCallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.js new file mode 100644 index 0000000000000..cee3bc6e5eccb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInCallback.ts] //// + +//// [numericCompoundAssignmentInCallback.ts] +function createConsumer(count: number) { + return () => { + if (count === 0) return; + count -= 1; + }; +} + + +//// [numericCompoundAssignmentInCallback.js] +"use strict"; +function createConsumer(count) { + return () => { + if (count === 0) + return; + count -= 1; + }; +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.symbols new file mode 100644 index 0000000000000..0dd38c58724c8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInCallback.ts] //// + +=== numericCompoundAssignmentInCallback.ts === +function createConsumer(count: number) { +>createConsumer : Symbol(createConsumer, Decl(numericCompoundAssignmentInCallback.ts, 0, 0)) +>count : Symbol(count, Decl(numericCompoundAssignmentInCallback.ts, 0, 24)) + + return () => { + if (count === 0) return; +>count : Symbol(count, Decl(numericCompoundAssignmentInCallback.ts, 0, 24)) + + count -= 1; +>count : Symbol(count, Decl(numericCompoundAssignmentInCallback.ts, 0, 24)) + + }; +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.types new file mode 100644 index 0000000000000..ffc6d0d5e3b3f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentInCallback.types @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/numericCompoundAssignmentInCallback.ts] //// + +=== numericCompoundAssignmentInCallback.ts === +function createConsumer(count: number) { +>createConsumer : (count: number) => () => void +>count : number + + return () => { +>() => { if (count === 0) return; count -= 1; } : () => void + + if (count === 0) return; +>count === 0 : boolean +>count : number +>0 : 0 + + count -= 1; +>count -= 1 : number +>count : number +>1 : 1 + + }; +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInCallback.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInCallback.ts new file mode 100644 index 0000000000000..b2228e6c16db8 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentInCallback.ts @@ -0,0 +1,7 @@ +// @strict: true +function createConsumer(count: number) { + return () => { + if (count === 0) return; + count -= 1; + }; +} From 15572b7c4580e563ee9bd67b360073d5a048fae7 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:32:21 -0700 Subject: [PATCH 052/116] Add historical coverage: numeric property compound assignment after disjunction Seven pinned Orca assignments guarded against original source AST/lines. Low-cost agent extracted numeric initialization and full relevant loops/callback/disjunction; independently executed source-shaped witness retains original findIndex/Math.max route and DOM query, captured Math.min producer/init-before-subscription order and actual nullable disposable result, both sequential toEvict break loops/status and negative-Set guards, tool-call/result depth assignments and positive else-if, full index/slice/continue/optional-push route, actual this numeric field and Math.min/Math.max/discard route with real numeric getter/void signature. Item/status/message structures supply only used fields/discriminants; unused message reset/interruption details, prompt/parser bodies, terminal implementation/payload/API presence, actual cap constant value, buffer storage/constructor/runtime and final record construction are explicitly projected. Terminal onData uses a callable surface with optionality for the preserved typeof guard, not a recovered xterm SDK graph; parseToolInput uses unknown only for unused prompt payload, never a numeric operand. No full functions/configs/projects/bot builds claimed. Historical matrices use strict ES2015 probes/chronology-selected heads/shared current libraries, not recovered bot merge binaries. Four new distinct break/continue/captured-callback/this-disjunction minimal forms plus existing early-return and positive/negative branch controls all independently give before0/first2322/later0/current0, with individual mutation lines and exact message guarded. Initial agent subscription-before-initialization and undefined-return projections were rejected/repaired before execution. Exact linked IDs: b54361cdd78b904b. This independent minimal testcase preserves numeric property compound assignment after disjunction; existing early-return/while/for/else cases share the root but not this control-flow form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566356 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...pertyCompoundAssignmentAfterDisjunction.js | 22 ++++++++++++ ...CompoundAssignmentAfterDisjunction.symbols | 27 +++++++++++++++ ...tyCompoundAssignmentAfterDisjunction.types | 34 +++++++++++++++++++ ...pertyCompoundAssignmentAfterDisjunction.ts | 8 +++++ 4 files changed, 91 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.types create mode 100644 tsc/testdata/tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.js b/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.js new file mode 100644 index 0000000000000..842869d40c63a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.js @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts] //// + +//// [numericPropertyCompoundAssignmentAfterDisjunction.ts] +class Decoder { + remaining = 0; + consume(size: number) { + if (this.remaining === 0 || size === 0) return; + this.remaining -= size; + } +} + + +//// [numericPropertyCompoundAssignmentAfterDisjunction.js] +"use strict"; +class Decoder { + remaining = 0; + consume(size) { + if (this.remaining === 0 || size === 0) + return; + this.remaining -= size; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.symbols b/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.symbols new file mode 100644 index 0000000000000..fe93dc94203d8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts] //// + +=== numericPropertyCompoundAssignmentAfterDisjunction.ts === +class Decoder { +>Decoder : Symbol(Decoder, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 0)) + + remaining = 0; +>remaining : Symbol(Decoder.remaining, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 15)) + + consume(size: number) { +>consume : Symbol(Decoder.consume, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 1, 18)) +>size : Symbol(size, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 2, 12)) + + if (this.remaining === 0 || size === 0) return; +>this.remaining : Symbol(Decoder.remaining, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 15)) +>this : Symbol(Decoder, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 0)) +>remaining : Symbol(Decoder.remaining, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 15)) +>size : Symbol(size, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 2, 12)) + + this.remaining -= size; +>this.remaining : Symbol(Decoder.remaining, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 15)) +>this : Symbol(Decoder, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 0)) +>remaining : Symbol(Decoder.remaining, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 0, 15)) +>size : Symbol(size, Decl(numericPropertyCompoundAssignmentAfterDisjunction.ts, 2, 12)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.types b/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.types new file mode 100644 index 0000000000000..e44d3de070c02 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericPropertyCompoundAssignmentAfterDisjunction.types @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts] //// + +=== numericPropertyCompoundAssignmentAfterDisjunction.ts === +class Decoder { +>Decoder : Decoder + + remaining = 0; +>remaining : number +>0 : 0 + + consume(size: number) { +>consume : (size: number) => void +>size : number + + if (this.remaining === 0 || size === 0) return; +>this.remaining === 0 || size === 0 : boolean +>this.remaining === 0 : boolean +>this.remaining : number +>this : this +>remaining : number +>0 : 0 +>size === 0 : boolean +>size : number +>0 : 0 + + this.remaining -= size; +>this.remaining -= size : number +>this.remaining : number +>this : this +>remaining : number +>size : number + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts b/tsc/testdata/tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts new file mode 100644 index 0000000000000..11b38a4226bbe --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericPropertyCompoundAssignmentAfterDisjunction.ts @@ -0,0 +1,8 @@ +// @strict: true +class Decoder { + remaining = 0; + consume(size: number) { + if (this.remaining === 0 || size === 0) return; + this.remaining -= size; + } +} From 9597cc327882f6ee5cfcec747fc9058a985e68bd Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:49:03 -0700 Subject: [PATCH 053/116] Add historical coverage: numeric compound assignments in nonzero branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exactly fourteen pinned tldraw sites. Real editor→tlschema→Arrow/BaseShape exports and props generic route, bend/scale:number, TLResizeInfo scaleX/Y:number, real Editor.getCurrentTheme():TLTheme strokeWidth:number, Record STROKE_SIZES, numeric BOUND_ARROW_OFFSET10 and boolean Vec.DistMin signature guarded. Resize retains actual destructures/Math.abs and all four sign branches with all six original zero-guarded *= assignments; normalized anchors/bindings/vector/runtime are projected out. Both offset witnesses retain zero initialization, numeric addition/multiplication through actual scale field, original DistMin condition and entire original conjunction/else-if mutation branches (eight sites). Stroke-offset values and whether the full point/shape/geometry conditions assign them are explicitly projected to guarded numeric parameters; unused point values are unknown only as boolean-API inputs, never numeric operands. Does not claim full geometry functions/configs/projects or bot installations. Two minimal tests preserve sequential nonzero-branch writes and conjunctive/else-if two-variable facts. Each source/reduced/integrated site has exact first-report2322 message/individual line guard and before/later/current clean controls, using chronology-selected heads/shared current libraries, not recovered bot merge binaries. Related early-return/while/for/else numeric tests share the cause but not these direct nonzero guards/sequential writes or conjunctive alternatives. This independent minimal testcase preserves numeric compound assignments in nonzero branch; no SDK enters the suite. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566504 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...mericCompoundAssignmentsInNonzeroBranch.js | 19 ++++++++++++++ ...CompoundAssignmentsInNonzeroBranch.symbols | 20 ++++++++++++++ ...icCompoundAssignmentsInNonzeroBranch.types | 26 +++++++++++++++++++ ...mericCompoundAssignmentsInNonzeroBranch.ts | 7 +++++ 4 files changed, 72 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.js new file mode 100644 index 0000000000000..95e27a445d2bc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts] //// + +//// [numericCompoundAssignmentsInNonzeroBranch.ts] +function scale(value: number, factor: number) { + if (value !== 0) { + value *= -1; + value *= factor; + } +} + + +//// [numericCompoundAssignmentsInNonzeroBranch.js] +"use strict"; +function scale(value, factor) { + if (value !== 0) { + value *= -1; + value *= factor; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.symbols new file mode 100644 index 0000000000000..a23ca75d97764 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts] //// + +=== numericCompoundAssignmentsInNonzeroBranch.ts === +function scale(value: number, factor: number) { +>scale : Symbol(scale, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 0)) +>value : Symbol(value, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 15)) +>factor : Symbol(factor, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 29)) + + if (value !== 0) { +>value : Symbol(value, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 15)) + + value *= -1; +>value : Symbol(value, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 15)) + + value *= factor; +>value : Symbol(value, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 15)) +>factor : Symbol(factor, Decl(numericCompoundAssignmentsInNonzeroBranch.ts, 0, 29)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.types new file mode 100644 index 0000000000000..c4ae0b071a6dc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsInNonzeroBranch.types @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts] //// + +=== numericCompoundAssignmentsInNonzeroBranch.ts === +function scale(value: number, factor: number) { +>scale : (value: number, factor: number) => void +>value : number +>factor : number + + if (value !== 0) { +>value !== 0 : boolean +>value : number +>0 : 0 + + value *= -1; +>value *= -1 : number +>value : number +>-1 : -1 +>1 : 1 + + value *= factor; +>value *= factor : number +>value : number +>factor : number + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts new file mode 100644 index 0000000000000..f4a203b45dbe0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsInNonzeroBranch.ts @@ -0,0 +1,7 @@ +// @strict: true +function scale(value: number, factor: number) { + if (value !== 0) { + value *= -1; + value *= factor; + } +} From 678cdc05d3d06bda0248cdc18b5d1273e1efbb95 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 13:49:07 -0700 Subject: [PATCH 054/116] Add historical coverage: numeric compound assignments after conjunction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exactly fourteen pinned tldraw sites. Real editor→tlschema→Arrow/BaseShape exports and props generic route, bend/scale:number, TLResizeInfo scaleX/Y:number, real Editor.getCurrentTheme():TLTheme strokeWidth:number, Record STROKE_SIZES, numeric BOUND_ARROW_OFFSET10 and boolean Vec.DistMin signature guarded. Resize retains actual destructures/Math.abs and all four sign branches with all six original zero-guarded *= assignments; normalized anchors/bindings/vector/runtime are projected out. Both offset witnesses retain zero initialization, numeric addition/multiplication through actual scale field, original DistMin condition and entire original conjunction/else-if mutation branches (eight sites). Stroke-offset values and whether the full point/shape/geometry conditions assign them are explicitly projected to guarded numeric parameters; unused point values are unknown only as boolean-API inputs, never numeric operands. Does not claim full geometry functions/configs/projects or bot installations. Two minimal tests preserve sequential nonzero-branch writes and conjunctive/else-if two-variable facts. Each source/reduced/integrated site has exact first-report2322 message/individual line guard and before/later/current clean controls, using chronology-selected heads/shared current libraries, not recovered bot merge binaries. Related early-return/while/for/else numeric tests share the cause but not these direct nonzero guards/sequential writes or conjunctive alternatives. This independent minimal testcase preserves numeric compound assignments after conjunction; no SDK enters the suite. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566504 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ericCompoundAssignmentsAfterConjunction.js | 29 ++++++++++ ...ompoundAssignmentsAfterConjunction.symbols | 32 +++++++++++ ...cCompoundAssignmentsAfterConjunction.types | 53 +++++++++++++++++++ ...ericCompoundAssignmentsAfterConjunction.ts | 11 ++++ 4 files changed, 125 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.js create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.types create mode 100644 tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.js b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.js new file mode 100644 index 0000000000000..c08b89db1bacd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.js @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts] //// + +//// [numericCompoundAssignmentsAfterConjunction.ts] +function scale(left: number, right: number) { + if (left !== 0 && right !== 0) { + left *= -1.5; + right *= -1.5; + } else if (left !== 0) { + left *= -2; + } else if (right !== 0) { + right *= -2; + } +} + + +//// [numericCompoundAssignmentsAfterConjunction.js] +"use strict"; +function scale(left, right) { + if (left !== 0 && right !== 0) { + left *= -1.5; + right *= -1.5; + } + else if (left !== 0) { + left *= -2; + } + else if (right !== 0) { + right *= -2; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.symbols b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.symbols new file mode 100644 index 0000000000000..fad4cce4d0fa7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts] //// + +=== numericCompoundAssignmentsAfterConjunction.ts === +function scale(left: number, right: number) { +>scale : Symbol(scale, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 0)) +>left : Symbol(left, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 15)) +>right : Symbol(right, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 28)) + + if (left !== 0 && right !== 0) { +>left : Symbol(left, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 15)) +>right : Symbol(right, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 28)) + + left *= -1.5; +>left : Symbol(left, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 15)) + + right *= -1.5; +>right : Symbol(right, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 28)) + + } else if (left !== 0) { +>left : Symbol(left, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 15)) + + left *= -2; +>left : Symbol(left, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 15)) + + } else if (right !== 0) { +>right : Symbol(right, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 28)) + + right *= -2; +>right : Symbol(right, Decl(numericCompoundAssignmentsAfterConjunction.ts, 0, 28)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.types b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.types new file mode 100644 index 0000000000000..e049be1be5520 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/numericCompoundAssignmentsAfterConjunction.types @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts] //// + +=== numericCompoundAssignmentsAfterConjunction.ts === +function scale(left: number, right: number) { +>scale : (left: number, right: number) => void +>left : number +>right : number + + if (left !== 0 && right !== 0) { +>left !== 0 && right !== 0 : boolean +>left !== 0 : boolean +>left : number +>0 : 0 +>right !== 0 : boolean +>right : number +>0 : 0 + + left *= -1.5; +>left *= -1.5 : number +>left : number +>-1.5 : -1.5 +>1.5 : 1.5 + + right *= -1.5; +>right *= -1.5 : number +>right : number +>-1.5 : -1.5 +>1.5 : 1.5 + + } else if (left !== 0) { +>left !== 0 : boolean +>left : number +>0 : 0 + + left *= -2; +>left *= -2 : number +>left : number +>-2 : -2 +>2 : 2 + + } else if (right !== 0) { +>right !== 0 : boolean +>right : number +>0 : 0 + + right *= -2; +>right *= -2 : number +>right : number +>-2 : -2 +>2 : 2 + } +} + diff --git a/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts new file mode 100644 index 0000000000000..fbe588209cb85 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/numericCompoundAssignmentsAfterConjunction.ts @@ -0,0 +1,11 @@ +// @strict: true +function scale(left: number, right: number) { + if (left !== 0 && right !== 0) { + left *= -1.5; + right *= -1.5; + } else if (left !== 0) { + left *= -2; + } else if (right !== 0) { + right *= -2; + } +} From a06c01bcefb55b8a6f8ad7dd61dbc76d04fc14c1 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 14:14:47 -0700 Subject: [PATCH 055/116] Add historical coverage: indexed any predicate in for loop Entire original eighteen-file source program using actual tsconfig include root and all original semantic flags; only output disabled/incremental false/types[] discovery isolation. Exact PR base/head checkers and their separate original libraries, not recovered bot merge binaries. Actual report is fragment() line108 with let index declared in for initializer, NOT preceding h() loop's outer mutable index; erroneous agent excerpt explicitly rejected. Minimal eleven-line candidate removes unrelated vnode data/children/runtime fields while retaining any base, string|number predicate, narrower string|undefined sink, loop-local incremented index and assignment back to indexed element. Current native candidate0. Added PR conformance tests2/3 are absent in current tree and neither itself covers this exact any predicate/string sink form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60715#issuecomment-2529191401 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/indexedAnyPredicateInForLoop.js | 23 +++++++++ .../indexedAnyPredicateInForLoop.symbols | 37 +++++++++++++++ .../indexedAnyPredicateInForLoop.types | 47 +++++++++++++++++++ .../compiler/indexedAnyPredicateInForLoop.ts | 11 +++++ 4 files changed, 118 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.js create mode 100644 tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.types create mode 100644 tsc/testdata/tests/cases/compiler/indexedAnyPredicateInForLoop.ts diff --git a/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.js b/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.js new file mode 100644 index 0000000000000..d9256a80c2f01 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/indexedAnyPredicateInForLoop.ts] //// + +//// [indexedAnyPredicateInForLoop.ts] +declare function isPrimitive(value: any): value is string | number; +declare function createText(text: string | undefined): object; +function normalize(children: any) { + for (let index = 0; index < children.length; ++index) { + if (isPrimitive(children[index])) { + children[index] = createText(children[index]); + } + } +} + + +//// [indexedAnyPredicateInForLoop.js] +"use strict"; +function normalize(children) { + for (let index = 0; index < children.length; ++index) { + if (isPrimitive(children[index])) { + children[index] = createText(children[index]); + } + } +} diff --git a/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.symbols b/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.symbols new file mode 100644 index 0000000000000..90f6f89c39e75 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/indexedAnyPredicateInForLoop.ts] //// + +=== indexedAnyPredicateInForLoop.ts === +declare function isPrimitive(value: any): value is string | number; +>isPrimitive : Symbol(isPrimitive, Decl(indexedAnyPredicateInForLoop.ts, 0, 0)) +>value : Symbol(value, Decl(indexedAnyPredicateInForLoop.ts, 0, 29)) +>value : Symbol(value, Decl(indexedAnyPredicateInForLoop.ts, 0, 29)) + +declare function createText(text: string | undefined): object; +>createText : Symbol(createText, Decl(indexedAnyPredicateInForLoop.ts, 0, 67)) +>text : Symbol(text, Decl(indexedAnyPredicateInForLoop.ts, 1, 28)) + +function normalize(children: any) { +>normalize : Symbol(normalize, Decl(indexedAnyPredicateInForLoop.ts, 1, 62)) +>children : Symbol(children, Decl(indexedAnyPredicateInForLoop.ts, 2, 19)) + + for (let index = 0; index < children.length; ++index) { +>index : Symbol(index, Decl(indexedAnyPredicateInForLoop.ts, 3, 12)) +>index : Symbol(index, Decl(indexedAnyPredicateInForLoop.ts, 3, 12)) +>children : Symbol(children, Decl(indexedAnyPredicateInForLoop.ts, 2, 19)) +>index : Symbol(index, Decl(indexedAnyPredicateInForLoop.ts, 3, 12)) + + if (isPrimitive(children[index])) { +>isPrimitive : Symbol(isPrimitive, Decl(indexedAnyPredicateInForLoop.ts, 0, 0)) +>children : Symbol(children, Decl(indexedAnyPredicateInForLoop.ts, 2, 19)) +>index : Symbol(index, Decl(indexedAnyPredicateInForLoop.ts, 3, 12)) + + children[index] = createText(children[index]); +>children : Symbol(children, Decl(indexedAnyPredicateInForLoop.ts, 2, 19)) +>index : Symbol(index, Decl(indexedAnyPredicateInForLoop.ts, 3, 12)) +>createText : Symbol(createText, Decl(indexedAnyPredicateInForLoop.ts, 0, 67)) +>children : Symbol(children, Decl(indexedAnyPredicateInForLoop.ts, 2, 19)) +>index : Symbol(index, Decl(indexedAnyPredicateInForLoop.ts, 3, 12)) + } + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.types b/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.types new file mode 100644 index 0000000000000..1409ee75961c8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexedAnyPredicateInForLoop.types @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/indexedAnyPredicateInForLoop.ts] //// + +=== indexedAnyPredicateInForLoop.ts === +declare function isPrimitive(value: any): value is string | number; +>isPrimitive : (value: any) => value is string | number +>value : any + +declare function createText(text: string | undefined): object; +>createText : (text: string | undefined) => object +>text : string | undefined + +function normalize(children: any) { +>normalize : (children: any) => void +>children : any + + for (let index = 0; index < children.length; ++index) { +>index : number +>0 : 0 +>index < children.length : boolean +>index : number +>children.length : any +>children : any +>length : any +>++index : number +>index : number + + if (isPrimitive(children[index])) { +>isPrimitive(children[index]) : boolean +>isPrimitive : (value: any) => value is string | number +>children[index] : any +>children : any +>index : number + + children[index] = createText(children[index]); +>children[index] = createText(children[index]) : object +>children[index] : any +>children : any +>index : number +>createText(children[index]) : object +>createText : (text: string | undefined) => object +>children[index] : any +>children : any +>index : number + } + } +} + diff --git a/tsc/testdata/tests/cases/compiler/indexedAnyPredicateInForLoop.ts b/tsc/testdata/tests/cases/compiler/indexedAnyPredicateInForLoop.ts new file mode 100644 index 0000000000000..6b48db8b70fb8 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/indexedAnyPredicateInForLoop.ts @@ -0,0 +1,11 @@ +// @target: es2015 +// @strict: true +declare function isPrimitive(value: any): value is string | number; +declare function createText(text: string | undefined): object; +function normalize(children: any) { + for (let index = 0; index < children.length; ++index) { + if (isPrimitive(children[index])) { + children[index] = createText(children[index]); + } + } +} From 550ee3120b2ea96a338e3ec118a6383d9c4cf22e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 14:14:50 -0700 Subject: [PATCH 056/116] Add historical coverage: default weak map inferred property assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original exact source aliases, Window global augmentation, nested function full parameter tuple, win alias, entire unannotated object initializer and exact reported assignment retained. Unrelated snapshot/render/runtime code and imports projected away with explicit external-module marker; no recovered bot installation/full-project claim. Actual reported standalone trace-viewer config used, NOT root config; semantic flags retained, only paths/ambient discovery/include/references scoped away. Exact PR checkers and their OWN original libraries. Cross-checker/library swaps isolate actual explicit-out variance library change, not guessed WeakKey addition. Minimal es2023 lib intentionally freezes pre-upsert collection API; original source uses ESNext. Current original-source native sole2322 is retained: current ES2026 collection augmentation adds getOrInsertComputed callback key, while changing ONLY source lib ESNext→ES2023 gives0. NOT claiming original-native0 or that today's ESNext library preserves historical acceptance. Root source key Element reduced to a one-property object key and unused value payload reduced to number, retaining unconstrained default constructor, separately inferred object property and deferred narrower assignment. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62973#issuecomment-3740953606 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../defaultWeakMapInferredPropertyAssignment.js | 11 +++++++++++ ...aultWeakMapInferredPropertyAssignment.symbols | 15 +++++++++++++++ ...efaultWeakMapInferredPropertyAssignment.types | 16 ++++++++++++++++ .../defaultWeakMapInferredPropertyAssignment.ts | 5 +++++ 4 files changed, 47 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.js create mode 100644 tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.js b/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.js new file mode 100644 index 0000000000000..20bddf727487d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.js @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts] //// + +//// [defaultWeakMapInferredPropertyAssignment.ts] +const frameInfo = { frames: new WeakMap() }; +const target: { frames: WeakMap<{ id: string }, number> } = frameInfo; + + +//// [defaultWeakMapInferredPropertyAssignment.js] +"use strict"; +const frameInfo = { frames: new WeakMap() }; +const target = frameInfo; diff --git a/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.symbols b/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.symbols new file mode 100644 index 0000000000000..38d0d548057a2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts] //// + +=== defaultWeakMapInferredPropertyAssignment.ts === +const frameInfo = { frames: new WeakMap() }; +>frameInfo : Symbol(frameInfo, Decl(defaultWeakMapInferredPropertyAssignment.ts, 0, 5)) +>frames : Symbol(frames, Decl(defaultWeakMapInferredPropertyAssignment.ts, 0, 19)) +>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +const target: { frames: WeakMap<{ id: string }, number> } = frameInfo; +>target : Symbol(target, Decl(defaultWeakMapInferredPropertyAssignment.ts, 1, 5)) +>frames : Symbol(frames, Decl(defaultWeakMapInferredPropertyAssignment.ts, 1, 15)) +>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>id : Symbol(id, Decl(defaultWeakMapInferredPropertyAssignment.ts, 1, 33)) +>frameInfo : Symbol(frameInfo, Decl(defaultWeakMapInferredPropertyAssignment.ts, 0, 5)) + diff --git a/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.types b/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.types new file mode 100644 index 0000000000000..e3c5579725a9c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultWeakMapInferredPropertyAssignment.types @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts] //// + +=== defaultWeakMapInferredPropertyAssignment.ts === +const frameInfo = { frames: new WeakMap() }; +>frameInfo : { frames: WeakMap; } +>{ frames: new WeakMap() } : { frames: WeakMap; } +>frames : WeakMap +>new WeakMap() : WeakMap +>WeakMap : WeakMapConstructor + +const target: { frames: WeakMap<{ id: string }, number> } = frameInfo; +>target : { frames: WeakMap<{ id: string; }, number>; } +>frames : WeakMap<{ id: string; }, number> +>id : string +>frameInfo : { frames: WeakMap; } + diff --git a/tsc/testdata/tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts b/tsc/testdata/tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts new file mode 100644 index 0000000000000..f4d6f46179395 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts @@ -0,0 +1,5 @@ +// @target: esnext +// @lib: es2023 +// @strict: true +const frameInfo = { frames: new WeakMap() }; +const target: { frames: WeakMap<{ id: string }, number> } = frameInfo; From 400ae315b145e3ea4eed02e816436702f4221219 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 14:47:29 -0700 Subject: [PATCH 057/116] Add historical coverage: jsx children excess property suppression Source-shaped projection, not complete original docs build or recovered bot install. Exact original target props/native renderer, styled factory callee/base/options, whole three genuine workspace styled declaration ASTs retained via source-release SDK with only build import-path normalization. Entire original LinkProps/NextLinkComposedProps/forwardRef type args and parameters plus original DeadLink body/static propTypes assignment retained; Link renderer null. Original Item JSX opening and all attribute order/expressions/spread/style retained, original children except one unrelated arrow icon replaced with span; iconElement/hasIcon declared by JSX/boolean shapes and sxChip original typed signature retained. Original source AppNav prop members/destructuring defaults selected only for used JSX fields; source UI click body/styles/outer navigation shell/hover and children propagation projected. Actual source-selected React/Emotion/Next/validator/Node/Mocha versions and SRIs guarded. Published MUI version equals source workspace version; entire styled declaration AST equality asserted, not a claim the full published package equals the entire pinned workspace or that npm's full transitive graph equals original pnpm snapshots. SDK confined to artifact tree; no runtime app execution. Both unsuppressed controls demonstrate real cause: before reports excess children on ignored opening tag; head sorts declaration-backed attributes first, reports excess href on later line outside ignore. Not component-union inference or a styled library declaration regression. Minimal13-line standalone JSX reduction/integrated testcase preserve this diagnostic-location change without any SDK. Native source and minimal ALSO report sole2322 at href: intended current diagnostic-location baseline for already-invalid JSX, NOT native acceptance0 and no implementation fix. Native target-props/LinkHref-not-any/no-href/no-children controls yield no additional errors. Removing only excess href restores before/head/native0; removing only children makes before/head/native all2322 at href, isolating the exact competing-child/attribute/line-suppression form. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61420#issuecomment-2725374079 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ildrenExcessPropertySuppression.errors.txt | 19 +++++++++++ .../jsxChildrenExcessPropertySuppression.js | 19 +++++++++++ ...xChildrenExcessPropertySuppression.symbols | 33 +++++++++++++++++++ ...jsxChildrenExcessPropertySuppression.types | 29 ++++++++++++++++ .../jsxChildrenExcessPropertySuppression.tsx | 13 ++++++++ 5 files changed, 113 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.js create mode 100644 tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.types create mode 100644 tsc/testdata/tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx diff --git a/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.errors.txt b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.errors.txt new file mode 100644 index 0000000000000..a7e11543046c2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.errors.txt @@ -0,0 +1,19 @@ +jsxChildrenExcessPropertySuppression.tsx(9,5): error TS2322: Type '{ depth: number; href: string; children: string; }' is not assignable to type '{ depth: number; }'. + Property 'href' does not exist on type '{ depth: number; }'. + + +==== jsxChildrenExcessPropertySuppression.tsx (1 errors) ==== + declare namespace JSX { + interface Element {} + interface ElementChildrenAttribute { children: {}; } + } + declare function Item(props: { depth: number }): JSX.Element; + // @ts-ignore + text; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.js b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.js new file mode 100644 index 0000000000000..b87a79fc6c338 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx] //// + +//// [jsxChildrenExcessPropertySuppression.tsx] +declare namespace JSX { + interface Element {} + interface ElementChildrenAttribute { children: {}; } +} +declare function Item(props: { depth: number }): JSX.Element; +// @ts-ignore +text; + + +//// [jsxChildrenExcessPropertySuppression.jsx] +"use strict"; +// @ts-ignore +text; diff --git a/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.symbols b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.symbols new file mode 100644 index 0000000000000..5240e8d208218 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.symbols @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx] //// + +=== jsxChildrenExcessPropertySuppression.tsx === +declare namespace JSX { +>JSX : Symbol(JSX, Decl(jsxChildrenExcessPropertySuppression.tsx, 0, 0)) + + interface Element {} +>Element : Symbol(Element, Decl(jsxChildrenExcessPropertySuppression.tsx, 0, 23)) + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(jsxChildrenExcessPropertySuppression.tsx, 1, 24)) +>children : Symbol(ElementChildrenAttribute.children, Decl(jsxChildrenExcessPropertySuppression.tsx, 2, 40)) +} +declare function Item(props: { depth: number }): JSX.Element; +>Item : Symbol(Item, Decl(jsxChildrenExcessPropertySuppression.tsx, 3, 1)) +>props : Symbol(props, Decl(jsxChildrenExcessPropertySuppression.tsx, 4, 22)) +>depth : Symbol(depth, Decl(jsxChildrenExcessPropertySuppression.tsx, 4, 30)) +>JSX : Symbol(JSX, Decl(jsxChildrenExcessPropertySuppression.tsx, 0, 0)) +>Element : Symbol(JSX.Element, Decl(jsxChildrenExcessPropertySuppression.tsx, 0, 23)) + +// @ts-ignore +Item : Symbol(Item, Decl(jsxChildrenExcessPropertySuppression.tsx, 3, 1)) + + depth={0} +>depth : Symbol(depth, Decl(jsxChildrenExcessPropertySuppression.tsx, 6, 5)) + + href="" +>href : Symbol(href, Decl(jsxChildrenExcessPropertySuppression.tsx, 7, 13)) + +>text; +>Item : Symbol(Item, Decl(jsxChildrenExcessPropertySuppression.tsx, 3, 1)) + diff --git a/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.types b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.types new file mode 100644 index 0000000000000..700352626a15e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxChildrenExcessPropertySuppression.types @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx] //// + +=== jsxChildrenExcessPropertySuppression.tsx === +declare namespace JSX { + interface Element {} + interface ElementChildrenAttribute { children: {}; } +>children : {} +} +declare function Item(props: { depth: number }): JSX.Element; +>Item : (props: { depth: number; }) => JSX.Element +>props : { depth: number; } +>depth : number +>JSX : any + +// @ts-ignore +text : JSX.Element +>Item : (props: { depth: number; }) => JSX.Element + + depth={0} +>depth : number +>0 : 0 + + href="" +>href : string + +>text; +>Item : (props: { depth: number; }) => JSX.Element + diff --git a/tsc/testdata/tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx b/tsc/testdata/tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx new file mode 100644 index 0000000000000..120bf9bcdea51 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/jsxChildrenExcessPropertySuppression.tsx @@ -0,0 +1,13 @@ +// @target: es2022 +// @jsx: preserve +// @strict: true +declare namespace JSX { + interface Element {} + interface ElementChildrenAttribute { children: {}; } +} +declare function Item(props: { depth: number }): JSX.Element; +// @ts-ignore +text; From ce28ae5663fb1bf81614ad76aae9fd804263e342 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 15:08:20 -0700 Subject: [PATCH 058/116] Add historical coverage: namespace function reserved default parameter Entire original pinned deps.ts plus genuine original EmbedDependency/type declarations, all original standalone semantic flags and omitted target/strict/alwaysStrict retained; only output disabled and ambient-discovery types[] isolated. Exact two original sites are defaulted parameter declaration at8 and if(static) use at67, NOT two declarations. Exact before0/head1212x2, separate original PR compiler/library pairs. IMPORTANT original native config gives sole5102 removed outFile; removing ONLY outFile in separate noEmit compatibility control gives same1212x2, NOT0. Explicit alwaysStrict:false control gives removed-option5108, NOT clean/non-strict native support. Current native intentionally requires strict code. Pre-existing convertKeywordsYes explicit alwaysStrict:false variant and parserStrictMode1 execute against both ORIGINAL checkers: actual static binding/type-parameter/type-reference/call gains exact1212 under head, absent under before; allowed object/interface/class property names are not mistaken for bindings. Their unrelated pre-existing18006/1213/2304 diagnostics are preserved/scoped, not claimed clean. Current convertKeywordsYes false variant is skipped for removed options; true variant and parserStrictMode1 characterize current strict bindings/call uses, NOT the actual namespace exported function DEFAULTED parameter and if-use form. No matching defaulted static parameter found in existing suite; salsa staticParam(static x=1) is malformed modifier syntax, not this value binding. New10-line self-contained namespaceFunctionReservedDefaultParameter case preserves namespace export/default false/if-use, before0/head1212x2/native1212x2. This deliberately adds a current-negative strict-policy characterization, not an acceptance-preserving fix or clean native-original claim. Not entire SandDance project/runtime build or bot binary reconstruction. No external SDK or declaration bundle enters suite. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61888#issuecomment-2982756277 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...unctionReservedDefaultParameter.errors.txt | 18 +++++++++++++ ...mespaceFunctionReservedDefaultParameter.js | 25 +++++++++++++++++++ ...ceFunctionReservedDefaultParameter.symbols | 19 ++++++++++++++ ...paceFunctionReservedDefaultParameter.types | 22 ++++++++++++++++ ...mespaceFunctionReservedDefaultParameter.ts | 10 ++++++++ 5 files changed, 94 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.js create mode 100644 tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.types create mode 100644 tsc/testdata/tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts diff --git a/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.errors.txt b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.errors.txt new file mode 100644 index 0000000000000..a0e7df42afc6b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.errors.txt @@ -0,0 +1,18 @@ +namespaceFunctionReservedDefaultParameter.ts(2,29): error TS1212: Identifier expected. 'static' is a reserved word in strict mode. +namespaceFunctionReservedDefaultParameter.ts(3,13): error TS1212: Identifier expected. 'static' is a reserved word in strict mode. + + +==== namespaceFunctionReservedDefaultParameter.ts (2 errors) ==== + namespace Dependencies { + export function scripts(static = false) { + ~~~~~~ +!!! error TS1212: Identifier expected. 'static' is a reserved word in strict mode. + if (static) { + ~~~~~~ +!!! error TS1212: Identifier expected. 'static' is a reserved word in strict mode. + return "static.js"; + } + return "interactive.js"; + } + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.js b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.js new file mode 100644 index 0000000000000..5bb89062243f6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts] //// + +//// [namespaceFunctionReservedDefaultParameter.ts] +namespace Dependencies { + export function scripts(static = false) { + if (static) { + return "static.js"; + } + return "interactive.js"; + } +} + + +//// [namespaceFunctionReservedDefaultParameter.js] +"use strict"; +var Dependencies; +(function (Dependencies) { + function scripts(static = false) { + if (static) { + return "static.js"; + } + return "interactive.js"; + } + Dependencies.scripts = scripts; +})(Dependencies || (Dependencies = {})); diff --git a/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.symbols b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.symbols new file mode 100644 index 0000000000000..62ef39acc0f2b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts] //// + +=== namespaceFunctionReservedDefaultParameter.ts === +namespace Dependencies { +>Dependencies : Symbol(Dependencies, Decl(namespaceFunctionReservedDefaultParameter.ts, 0, 0)) + + export function scripts(static = false) { +>scripts : Symbol(scripts, Decl(namespaceFunctionReservedDefaultParameter.ts, 0, 24)) +>static : Symbol(static, Decl(namespaceFunctionReservedDefaultParameter.ts, 1, 28)) + + if (static) { +>static : Symbol(static, Decl(namespaceFunctionReservedDefaultParameter.ts, 1, 28)) + + return "static.js"; + } + return "interactive.js"; + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.types b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.types new file mode 100644 index 0000000000000..b43c1d3dba508 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/namespaceFunctionReservedDefaultParameter.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts] //// + +=== namespaceFunctionReservedDefaultParameter.ts === +namespace Dependencies { +>Dependencies : typeof Dependencies + + export function scripts(static = false) { +>scripts : (static?: boolean) => "interactive.js" | "static.js" +>static : boolean +>false : false + + if (static) { +>static : boolean + + return "static.js"; +>"static.js" : "static.js" + } + return "interactive.js"; +>"interactive.js" : "interactive.js" + } +} + diff --git a/tsc/testdata/tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts b/tsc/testdata/tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts new file mode 100644 index 0000000000000..ae8c8fd03b058 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/namespaceFunctionReservedDefaultParameter.ts @@ -0,0 +1,10 @@ +// @target: es2015 + +namespace Dependencies { + export function scripts(static = false) { + if (static) { + return "static.js"; + } + return "interactive.js"; + } +} From 431f09a3f2e2256b6795c9516819aa912ac7dcd2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 15:32:24 -0700 Subject: [PATCH 059/116] Add historical coverage: promise all array assertion overlap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Genuine TypeORM0.3.25 SDK matches actual pinned source VERSION and relevant entire public generic signatures/aliases/class generic bounds/heritage via recursive AST guards: DataSource.manager, EntityManager.createQueryBuilder BOTH overloads, QueryBuilder.clone, SelectQueryBuilder.where/getOne, ObjectLiteral/EntityTarget. Entire actual Post/Author source classes AND EntitySchemas retained, only source SDK import redirected to genuine same-version package. Original two qb and destructuring/assertion statements copied VERBATIM, including real In([1]), clone/where, original string entity target and Post[] assertion. String target infers ObjectLiteral, NOT Post. DB setup/test runner/prepareData/assertions projected; connection uses actual DataSource type, no invented ORM declarations. Actual source-lock Node16 config16.1.4, Node16.18.126, tslib2.8.1 version/resolved/SRI guarded; original tests root→Node16 config semantics retained, output disabled and types[] discovery isolated. Published SDK graph NOT claimed equal to original workspace/full lock; relevant declaration ASTs guarded, own installed graph private. Historical whole witness before0/head exact2352x2 at source-linked assertions: [ObjectLiteral|null,ObjectLiteral|null] versus Post[]; complete original Post author/id/title missing-field diagnostic preserved. Native ORIGINAL config gives5108 node10+5102 downlevelIteration, NOT0. Separate module/resolution BOTH Node16 plus removing emit-only downlevelIteration gives0, with genuine ObjectLiteral|null result-equality/not-any controls. The14-line SDK-free reduction keeps actual any-index row/null promises/Promise.all/as required-property Entity[]; one required id suffices. Destructuring removal independently PRESERVES before0/head2352/native0, so omitted as unnecessary. Replacing any string index with unknown yields2352 BOTH before/head, demonstrating why that seemingly cleaner reduction is wrong. Ten historical source/candidate/counterfactual/integrated matrices asserted; native candidate/integrated0. Existing inferFromGenericFunctionReturnTypes3 has contextual Promise.all return arrays, NOT awaited assertion overlap; no matching awaited Promise.all→array assertion found in compiler suite. No full TypeORM/runtime DB/bot build or SDK blob in suite. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62174#issuecomment-3146021796 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../promiseAllArrayAssertionOverlap.js | 31 ++++++++++++++++++ .../promiseAllArrayAssertionOverlap.symbols | 32 +++++++++++++++++++ .../promiseAllArrayAssertionOverlap.types | 30 +++++++++++++++++ .../promiseAllArrayAssertionOverlap.ts | 14 ++++++++ 4 files changed, 107 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.js create mode 100644 tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.types create mode 100644 tsc/testdata/tests/cases/compiler/promiseAllArrayAssertionOverlap.ts diff --git a/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.js b/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.js new file mode 100644 index 0000000000000..1d7ea073d2f52 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.js @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/promiseAllArrayAssertionOverlap.ts] //// + +//// [promiseAllArrayAssertionOverlap.ts] +interface Row { + [name: string]: any; +} +interface Entity { + id: number; +} +declare const result: Promise; + +export async function load() { + return (await Promise.all([result, result])) as Entity[]; +} + + +//// [promiseAllArrayAssertionOverlap.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +export function load() { + return __awaiter(this, void 0, void 0, function* () { + return (yield Promise.all([result, result])); + }); +} diff --git a/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.symbols b/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.symbols new file mode 100644 index 0000000000000..64182bbd096f4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/promiseAllArrayAssertionOverlap.ts] //// + +=== promiseAllArrayAssertionOverlap.ts === +interface Row { +>Row : Symbol(Row, Decl(promiseAllArrayAssertionOverlap.ts, 0, 0)) + + [name: string]: any; +>name : Symbol(name, Decl(promiseAllArrayAssertionOverlap.ts, 1, 5)) +} +interface Entity { +>Entity : Symbol(Entity, Decl(promiseAllArrayAssertionOverlap.ts, 2, 1)) + + id: number; +>id : Symbol(Entity.id, Decl(promiseAllArrayAssertionOverlap.ts, 3, 18)) +} +declare const result: Promise; +>result : Symbol(result, Decl(promiseAllArrayAssertionOverlap.ts, 6, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Row : Symbol(Row, Decl(promiseAllArrayAssertionOverlap.ts, 0, 0)) + +export async function load() { +>load : Symbol(load, Decl(promiseAllArrayAssertionOverlap.ts, 6, 42)) + + return (await Promise.all([result, result])) as Entity[]; +>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>result : Symbol(result, Decl(promiseAllArrayAssertionOverlap.ts, 6, 13)) +>result : Symbol(result, Decl(promiseAllArrayAssertionOverlap.ts, 6, 13)) +>Entity : Symbol(Entity, Decl(promiseAllArrayAssertionOverlap.ts, 2, 1)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.types b/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.types new file mode 100644 index 0000000000000..d8ab523af8ceb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/promiseAllArrayAssertionOverlap.types @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/promiseAllArrayAssertionOverlap.ts] //// + +=== promiseAllArrayAssertionOverlap.ts === +interface Row { + [name: string]: any; +>name : string +} +interface Entity { + id: number; +>id : number +} +declare const result: Promise; +>result : Promise + +export async function load() { +>load : () => Promise + + return (await Promise.all([result, result])) as Entity[]; +>(await Promise.all([result, result])) as Entity[] : Entity[] +>(await Promise.all([result, result])) : (Row | null)[] +>await Promise.all([result, result]) : (Row | null)[] +>Promise.all([result, result]) : Promise<(Row | null)[]> +>Promise.all : { (values: Iterable>): Promise[]>; (values: T): Promise<{ -readonly [P in keyof T]: Awaited; }>; } +>Promise : PromiseConstructor +>all : { (values: Iterable>): Promise[]>; (values: T): Promise<{ -readonly [P in keyof T]: Awaited; }>; } +>[result, result] : Promise[] +>result : Promise +>result : Promise +} + diff --git a/tsc/testdata/tests/cases/compiler/promiseAllArrayAssertionOverlap.ts b/tsc/testdata/tests/cases/compiler/promiseAllArrayAssertionOverlap.ts new file mode 100644 index 0000000000000..83245f871bc77 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/promiseAllArrayAssertionOverlap.ts @@ -0,0 +1,14 @@ +// @strict: true +// @target: es2015 + +interface Row { + [name: string]: any; +} +interface Entity { + id: number; +} +declare const result: Promise; + +export async function load() { + return (await Promise.all([result, result])) as Entity[]; +} From 7e4259243a2b12d882be43a7ca174b6835987e49 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 15:37:38 -0700 Subject: [PATCH 060/116] Add historical coverage: object entries partial indexed write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete actual pinned ImportTransaction intersection, complete FieldMapping and complete applyFieldMappings function copied as exact AST source nodes, including nullable targets, payee→payee_name conditional, Partial result and final preview-field writes/assertion. No SDK needed or invented. Actual source root config recovered (no extends/child config), original target ES2022/libs/strictFunctionTypes/bundler/allowJs/checkJs/decorators etc retained; explicit unrelated Vite/Jest/Vitest global discovery, path discovery and incremental output projected. Ten original-checker/library matrices: source/candidate/integrated before0/head exactly2322 string→never; broad-mapping and uniform-row counterfactuals both0/0. Original native sole5102 downlevelIteration removed retained; separate removal ONLY that option native source0; native candidate/integrated0. Minimal finite entries mapping plus Partial numeric-field/string-index intersection write; strictfalse preserves actual source implicit nonstrict checks. Existing values/entries return inference, mappedTypeConstraints2 generic cast-and-read, computedPropertyBindingElementDeclarationNoCrash1 any-input computed object creation and fromEntries tests do not exercise this concrete indexed Partial write. Scope exactly one original ID, not all PR61074 reports. No full Actual build/bot installation claim. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../objectEntriesPartialIndexedWrite.js | 21 ++++++++++ .../objectEntriesPartialIndexedWrite.symbols | 39 ++++++++++++++++++ .../objectEntriesPartialIndexedWrite.types | 40 +++++++++++++++++++ .../objectEntriesPartialIndexedWrite.ts | 11 +++++ 4 files changed, 111 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.types create mode 100644 tsc/testdata/tests/cases/compiler/objectEntriesPartialIndexedWrite.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.js b/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.js new file mode 100644 index 0000000000000..c0a29c9aa01c0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/objectEntriesPartialIndexedWrite.ts] //// + +//// [objectEntriesPartialIndexedWrite.ts] +type Row = { amount: number } & Record; +export function copy(row: Row, mapping: { amount: string; notes: string }) { + const result: Partial = {}; + for (const [field, target] of Object.entries(mapping)) { + result[field] = row[target]; + } + return result; +} + + +//// [objectEntriesPartialIndexedWrite.js] +export function copy(row, mapping) { + const result = {}; + for (const [field, target] of Object.entries(mapping)) { + result[field] = row[target]; + } + return result; +} diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.symbols b/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.symbols new file mode 100644 index 0000000000000..22d67fa529098 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.symbols @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/objectEntriesPartialIndexedWrite.ts] //// + +=== objectEntriesPartialIndexedWrite.ts === +type Row = { amount: number } & Record; +>Row : Symbol(Row, Decl(objectEntriesPartialIndexedWrite.ts, 0, 0)) +>amount : Symbol(amount, Decl(objectEntriesPartialIndexedWrite.ts, 0, 12)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +export function copy(row: Row, mapping: { amount: string; notes: string }) { +>copy : Symbol(copy, Decl(objectEntriesPartialIndexedWrite.ts, 0, 55)) +>row : Symbol(row, Decl(objectEntriesPartialIndexedWrite.ts, 1, 21)) +>Row : Symbol(Row, Decl(objectEntriesPartialIndexedWrite.ts, 0, 0)) +>mapping : Symbol(mapping, Decl(objectEntriesPartialIndexedWrite.ts, 1, 30)) +>amount : Symbol(amount, Decl(objectEntriesPartialIndexedWrite.ts, 1, 41)) +>notes : Symbol(notes, Decl(objectEntriesPartialIndexedWrite.ts, 1, 57)) + + const result: Partial = {}; +>result : Symbol(result, Decl(objectEntriesPartialIndexedWrite.ts, 2, 9)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>Row : Symbol(Row, Decl(objectEntriesPartialIndexedWrite.ts, 0, 0)) + + for (const [field, target] of Object.entries(mapping)) { +>field : Symbol(field, Decl(objectEntriesPartialIndexedWrite.ts, 3, 16)) +>target : Symbol(target, Decl(objectEntriesPartialIndexedWrite.ts, 3, 22)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>mapping : Symbol(mapping, Decl(objectEntriesPartialIndexedWrite.ts, 1, 30)) + + result[field] = row[target]; +>result : Symbol(result, Decl(objectEntriesPartialIndexedWrite.ts, 2, 9)) +>field : Symbol(field, Decl(objectEntriesPartialIndexedWrite.ts, 3, 16)) +>row : Symbol(row, Decl(objectEntriesPartialIndexedWrite.ts, 1, 21)) +>target : Symbol(target, Decl(objectEntriesPartialIndexedWrite.ts, 3, 22)) + } + return result; +>result : Symbol(result, Decl(objectEntriesPartialIndexedWrite.ts, 2, 9)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.types b/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.types new file mode 100644 index 0000000000000..89a685315a29c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesPartialIndexedWrite.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/objectEntriesPartialIndexedWrite.ts] //// + +=== objectEntriesPartialIndexedWrite.ts === +type Row = { amount: number } & Record; +>Row : Row +>amount : number + +export function copy(row: Row, mapping: { amount: string; notes: string }) { +>copy : (row: Row, mapping: { amount: string; notes: string; }) => Partial +>row : Row +>mapping : { amount: string; notes: string; } +>amount : string +>notes : string + + const result: Partial = {}; +>result : Partial +>{} : {} + + for (const [field, target] of Object.entries(mapping)) { +>field : string +>target : string +>Object.entries(mapping) : [string, string][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>mapping : { amount: string; notes: string; } + + result[field] = row[target]; +>result[field] = row[target] : string +>result[field] : string +>result : Partial +>field : string +>row[target] : string +>row : Row +>target : string + } + return result; +>result : Partial +} + diff --git a/tsc/testdata/tests/cases/compiler/objectEntriesPartialIndexedWrite.ts b/tsc/testdata/tests/cases/compiler/objectEntriesPartialIndexedWrite.ts new file mode 100644 index 0000000000000..3d3f54f4c255c --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectEntriesPartialIndexedWrite.ts @@ -0,0 +1,11 @@ +// @target: es2022 +// @strict: false + +type Row = { amount: number } & Record; +export function copy(row: Row, mapping: { amount: string; notes: string }) { + const result: Partial = {}; + for (const [field, target] of Object.entries(mapping)) { + result[field] = row[target]; + } + return result; +} From 025d4b5817e29e7f89008253bd6baf8f48a2e9e2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 15:52:24 -0700 Subject: [PATCH 061/116] Add historical coverage: object from entries spread possible duplicates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actual pinned original entire static Record mapping initializer and both genuine React aliases, six actual SDK imports, entire FontAwesome callback body/defaults/wrapper retained; ONLY unrelated local LetterIcon property omitted, unrelated lookup/search methods/imports projected. Every THIRTY original collision property/line/message independently AST-linked. Whole actual original array of FontAwesome input values and icon.iconName map expression retained; inputs are NOT invented tuple keys. Genuine source Yarn v1 exact descriptor/SRI/archive-selected56-package SDK/React17.0.75 types/FontAwesome6.7.2, frozen complete original lock unchanged; all installed package versions and151 original resolution entries checked. SDK subset not full Outline app/bot install; private Yarn1.22.22 ignore-scripts/engines caveat explicit. Original standalone semantic flags/target/lib retained; path/project discovery omitted. Ten original-checker/library matrices: source0→THIRTY exact2783, candidate/integrated0→one2783, broad-name/nonoverlapping-key counterfactuals0/0. Genuine actual SDK name union includes bicycle even for faBagShopping; native positive union/not-any/component/React controls0 after explicitly removing only baseUrl and changing removed node10 resolution to bundler; ORIGINAL native5102+5108 retained, not called clean. Candidate/integrated native0. SDK-free five-line body preserves finite name union, original map→fromEntries→object spread inference and potential collision. Existing spreadDuplicate/Exact tests cover explicitly required properties, not mapped fromEntries potential keys; existing fromEntries tests lack this map/spread/collision form. Scope ONLY thirty original IconLibrary identities, not remaining Outline webhook or other PR61074 families. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...jectFromEntriesSpreadPossibleDuplicates.js | 15 ++++++++ ...romEntriesSpreadPossibleDuplicates.symbols | 27 +++++++++++++++ ...tFromEntriesSpreadPossibleDuplicates.types | 34 +++++++++++++++++++ ...jectFromEntriesSpreadPossibleDuplicates.ts | 8 +++++ 4 files changed, 84 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.types create mode 100644 tsc/testdata/tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.js b/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.js new file mode 100644 index 0000000000000..d3b80fb322b83 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts] //// + +//// [objectFromEntriesSpreadPossibleDuplicates.ts] +declare const icons: { iconName: "bicycle" | "book" }[]; +export const mapping = { + bicycle: 0, + ...Object.fromEntries(icons.map(icon => [icon.iconName, 1])), +}; + + +//// [objectFromEntriesSpreadPossibleDuplicates.js] +export const mapping = { + bicycle: 0, + ...Object.fromEntries(icons.map(icon => [icon.iconName, 1])), +}; diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.symbols b/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.symbols new file mode 100644 index 0000000000000..372daa391c854 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts] //// + +=== objectFromEntriesSpreadPossibleDuplicates.ts === +declare const icons: { iconName: "bicycle" | "book" }[]; +>icons : Symbol(icons, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 0, 13)) +>iconName : Symbol(iconName, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 0, 22)) + +export const mapping = { +>mapping : Symbol(mapping, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 1, 12)) + + bicycle: 0, +>bicycle : Symbol(bicycle, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 1, 24)) + + ...Object.fromEntries(icons.map(icon => [icon.iconName, 1])), +>Object.fromEntries : Symbol(ObjectConstructor.fromEntries, Decl(lib.es2019.object.d.ts, --, --), Decl(lib.es2019.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>fromEntries : Symbol(ObjectConstructor.fromEntries, Decl(lib.es2019.object.d.ts, --, --), Decl(lib.es2019.object.d.ts, --, --)) +>icons.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>icons : Symbol(icons, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 0, 13)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>icon : Symbol(icon, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 3, 36)) +>icon.iconName : Symbol(iconName, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 0, 22)) +>icon : Symbol(icon, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 3, 36)) +>iconName : Symbol(iconName, Decl(objectFromEntriesSpreadPossibleDuplicates.ts, 0, 22)) + +}; + diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.types b/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.types new file mode 100644 index 0000000000000..9f37475f8d75c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesSpreadPossibleDuplicates.types @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts] //// + +=== objectFromEntriesSpreadPossibleDuplicates.ts === +declare const icons: { iconName: "bicycle" | "book" }[]; +>icons : { iconName: "bicycle" | "book"; }[] +>iconName : "bicycle" | "book" + +export const mapping = { +>mapping : { bicycle: number; } +>{ bicycle: 0, ...Object.fromEntries(icons.map(icon => [icon.iconName, 1])),} : { bicycle: number; } + + bicycle: 0, +>bicycle : number +>0 : 0 + + ...Object.fromEntries(icons.map(icon => [icon.iconName, 1])), +>Object.fromEntries(icons.map(icon => [icon.iconName, 1])) : { [k: string]: number; } +>Object.fromEntries : { (entries: Iterable): { [k: string]: T; }; (entries: Iterable): any; } +>Object : ObjectConstructor +>fromEntries : { (entries: Iterable): { [k: string]: T; }; (entries: Iterable): any; } +>icons.map(icon => [icon.iconName, 1]) : ["bicycle" | "book", number][] +>icons.map : (callbackfn: (value: { iconName: "bicycle" | "book"; }, index: number, array: { iconName: "bicycle" | "book"; }[]) => U, thisArg?: any) => U[] +>icons : { iconName: "bicycle" | "book"; }[] +>map : (callbackfn: (value: { iconName: "bicycle" | "book"; }, index: number, array: { iconName: "bicycle" | "book"; }[]) => U, thisArg?: any) => U[] +>icon => [icon.iconName, 1] : (icon: { iconName: "bicycle" | "book"; }) => ["bicycle" | "book", number] +>icon : { iconName: "bicycle" | "book"; } +>[icon.iconName, 1] : ["bicycle" | "book", number] +>icon.iconName : "bicycle" | "book" +>icon : { iconName: "bicycle" | "book"; } +>iconName : "bicycle" | "book" +>1 : 1 + +}; + diff --git a/tsc/testdata/tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts b/tsc/testdata/tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts new file mode 100644 index 0000000000000..b65323ade4e1b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectFromEntriesSpreadPossibleDuplicates.ts @@ -0,0 +1,8 @@ +// @target: es2020 +// @strict: true + +declare const icons: { iconName: "bicycle" | "book" }[]; +export const mapping = { + bicycle: 0, + ...Object.fromEntries(icons.map(icon => [icon.iconName, 1])), +}; From 20704e504242e9e3eb938a7a29d6ed2a44d4315d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 16:06:20 -0700 Subject: [PATCH 062/116] Add historical coverage: object entries object array narrowing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ONLY exact Coc deepIterate ID, not registry same-repo site. ENTIRE source-pinned deepIterate body and ENTIRE actual objectLiteral guard function copied verbatim as AST declarations; source import redirected to exact predicate declaration only. No guessed type guard, recursion or callback replacement. Genuine source npm-lock tslib2.6.3 (^2.6.3 actual root) one-package frozen closure/SRI/descriptor guard preserves ORIGINAL importHelpers/esModuleInterop; initial missing-helper2354 rejected, NOT silenced by disabling helpers or guessed newer helper. Actual standalone no-child config preserved including stricttrue/noImplicitAnyfalse/strictNullChecksfalse/ES2017 and explicit original libs; only project discovery isolated. Original before0/head sole2339 val.forEach never, native ORIGINALsole5108 removednode10, separate actual module+resolution Node16 compatibility0. Eight original-checker/library matrices: source/candidate/integrated0→same2339; explicit Record counterfactual0/0 isolates empty keyof object inference, not Array.isArray implementation. SDK-free six-line candidate/integrated retain object-typed entries→Array.isArray guard→forEach; both native0. Existing useObjectValuesAndEntries1 empty-interface result baseline lacks subsequent array-guard/dereference, and mappedTypeConstraints2 uses generic typed keys/cast/read, not empty-key object value flow. No whole Coc/build/bot install claim. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../objectEntriesObjectArrayNarrowing.js | 18 +++++++++++ .../objectEntriesObjectArrayNarrowing.symbols | 26 ++++++++++++++++ .../objectEntriesObjectArrayNarrowing.types | 30 +++++++++++++++++++ .../objectEntriesObjectArrayNarrowing.ts | 9 ++++++ 4 files changed, 83 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.types create mode 100644 tsc/testdata/tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.js b/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.js new file mode 100644 index 0000000000000..a390fd1b72f27 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts] //// + +//// [objectEntriesObjectArrayNarrowing.ts] +declare const record: object; +for (const [, value] of Object.entries(record)) { + if (Array.isArray(value)) { + value.forEach(() => {}); + } +} + + +//// [objectEntriesObjectArrayNarrowing.js] +"use strict"; +for (const [, value] of Object.entries(record)) { + if (Array.isArray(value)) { + value.forEach(() => { }); + } +} diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.symbols b/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.symbols new file mode 100644 index 0000000000000..573801e00db50 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.symbols @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts] //// + +=== objectEntriesObjectArrayNarrowing.ts === +declare const record: object; +>record : Symbol(record, Decl(objectEntriesObjectArrayNarrowing.ts, 0, 13)) + +for (const [, value] of Object.entries(record)) { +>value : Symbol(value, Decl(objectEntriesObjectArrayNarrowing.ts, 1, 13)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>record : Symbol(record, Decl(objectEntriesObjectArrayNarrowing.ts, 0, 13)) + + if (Array.isArray(value)) { +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 1 more) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(objectEntriesObjectArrayNarrowing.ts, 1, 13)) + + value.forEach(() => {}); +>value.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(objectEntriesObjectArrayNarrowing.ts, 1, 13)) +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.types b/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.types new file mode 100644 index 0000000000000..98ae6838036f8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesObjectArrayNarrowing.types @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts] //// + +=== objectEntriesObjectArrayNarrowing.ts === +declare const record: object; +>record : object + +for (const [, value] of Object.entries(record)) { +>value : any +>Object.entries(record) : [string, any][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>record : object + + if (Array.isArray(value)) { +>Array.isArray(value) : boolean +>Array.isArray : (arg: any) => arg is any[] +>Array : ArrayConstructor +>isArray : (arg: any) => arg is any[] +>value : any + + value.forEach(() => {}); +>value.forEach(() => {}) : void +>value.forEach : (callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any) => void +>value : any[] +>forEach : (callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any) => void +>() => {} : () => void + } +} + diff --git a/tsc/testdata/tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts b/tsc/testdata/tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts new file mode 100644 index 0000000000000..77200f4a07b7c --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectEntriesObjectArrayNarrowing.ts @@ -0,0 +1,9 @@ +// @target: es2017 +// @strict: true + +declare const record: object; +for (const [, value] of Object.entries(record)) { + if (Array.isArray(value)) { + value.forEach(() => {}); + } +} From f7c9ae575e4ee46ab9db1477f9ab87318e24cabd Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 16:24:27 -0700 Subject: [PATCH 063/116] Add historical coverage: object from entries additional property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only exact Focalboard identity. COMPLETE original12-member UserSettingKey enum and COMPLETE original exportUserSettings function copied as verbatim AST declarations, actual Object.values→map→fromEntries→timestamp mutation/Date.now/JSON.stringify retained. Genuine DOM localStorage declarations from ORIGINAL compiler libs, not invented storage SDK; unrelated IPC/Utils imports/classes/import functions omitted. Actual standalone ES2019/strict/null/noImplicitAny/allowJs/config flags preserved; isolated roots/no default ambient package discovery. Before0/headsole exact2339 timestamp; original native5102baseUrl+5108node10 retained; separate baseUrl removal+Node16 module/resolution source0. SDK-free three-line candidate and matching integrated test body (CRLF normalized) each0/head2339/native0. Broad key and existing-property counterfactuals0/0 isolate string-index loss rather than key/value tuple validity. No full Focalboard/bot install claim. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../objectFromEntriesAdditionalProperty.js | 12 ++++++++ ...bjectFromEntriesAdditionalProperty.symbols | 22 ++++++++++++++ .../objectFromEntriesAdditionalProperty.types | 29 +++++++++++++++++++ .../objectFromEntriesAdditionalProperty.ts | 6 ++++ 4 files changed, 69 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.types create mode 100644 tsc/testdata/tests/cases/compiler/objectFromEntriesAdditionalProperty.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.js b/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.js new file mode 100644 index 0000000000000..106270a93abb6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/objectFromEntriesAdditionalProperty.ts] //// + +//// [objectFromEntriesAdditionalProperty.ts] +declare const keys: ("language" | "theme")[]; +const settings = Object.fromEntries(keys.map(key => [key, ""])); +settings.timestamp = ""; + + +//// [objectFromEntriesAdditionalProperty.js] +"use strict"; +const settings = Object.fromEntries(keys.map(key => [key, ""])); +settings.timestamp = ""; diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.symbols b/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.symbols new file mode 100644 index 0000000000000..04abbfc6e0321 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/objectFromEntriesAdditionalProperty.ts] //// + +=== objectFromEntriesAdditionalProperty.ts === +declare const keys: ("language" | "theme")[]; +>keys : Symbol(keys, Decl(objectFromEntriesAdditionalProperty.ts, 0, 13)) + +const settings = Object.fromEntries(keys.map(key => [key, ""])); +>settings : Symbol(settings, Decl(objectFromEntriesAdditionalProperty.ts, 1, 5)) +>Object.fromEntries : Symbol(ObjectConstructor.fromEntries, Decl(lib.es2019.object.d.ts, --, --), Decl(lib.es2019.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>fromEntries : Symbol(ObjectConstructor.fromEntries, Decl(lib.es2019.object.d.ts, --, --), Decl(lib.es2019.object.d.ts, --, --)) +>keys.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(keys, Decl(objectFromEntriesAdditionalProperty.ts, 0, 13)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>key : Symbol(key, Decl(objectFromEntriesAdditionalProperty.ts, 1, 45)) +>key : Symbol(key, Decl(objectFromEntriesAdditionalProperty.ts, 1, 45)) + +settings.timestamp = ""; +>settings.timestamp : Symbol(__index, Decl(lib.es2019.object.d.ts, --, --)) +>settings : Symbol(settings, Decl(objectFromEntriesAdditionalProperty.ts, 1, 5)) +>timestamp : Symbol(__index, Decl(lib.es2019.object.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.types b/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.types new file mode 100644 index 0000000000000..37e5aba1baf7e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesAdditionalProperty.types @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/objectFromEntriesAdditionalProperty.ts] //// + +=== objectFromEntriesAdditionalProperty.ts === +declare const keys: ("language" | "theme")[]; +>keys : ("language" | "theme")[] + +const settings = Object.fromEntries(keys.map(key => [key, ""])); +>settings : { [k: string]: string; } +>Object.fromEntries(keys.map(key => [key, ""])) : { [k: string]: string; } +>Object.fromEntries : { (entries: Iterable): { [k: string]: T; }; (entries: Iterable): any; } +>Object : ObjectConstructor +>fromEntries : { (entries: Iterable): { [k: string]: T; }; (entries: Iterable): any; } +>keys.map(key => [key, ""]) : ["language" | "theme", string][] +>keys.map : (callbackfn: (value: "language" | "theme", index: number, array: ("language" | "theme")[]) => U, thisArg?: any) => U[] +>keys : ("language" | "theme")[] +>map : (callbackfn: (value: "language" | "theme", index: number, array: ("language" | "theme")[]) => U, thisArg?: any) => U[] +>key => [key, ""] : (key: "language" | "theme") => ["language" | "theme", string] +>key : "language" | "theme" +>[key, ""] : ["language" | "theme", string] +>key : "language" | "theme" +>"" : "" + +settings.timestamp = ""; +>settings.timestamp = "" : "" +>settings.timestamp : string +>settings : { [k: string]: string; } +>timestamp : string +>"" : "" + diff --git a/tsc/testdata/tests/cases/compiler/objectFromEntriesAdditionalProperty.ts b/tsc/testdata/tests/cases/compiler/objectFromEntriesAdditionalProperty.ts new file mode 100644 index 0000000000000..35363370d248e --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectFromEntriesAdditionalProperty.ts @@ -0,0 +1,6 @@ +// @target: es2019 +// @strict: true + +declare const keys: ("language" | "theme")[]; +const settings = Object.fromEntries(keys.map(key => [key, ""])); +settings.timestamp = ""; From 8da74486025961a9c6077fb0bfa6aa766d85ba00 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 16:56:08 -0700 Subject: [PATCH 064/116] Add historical coverage: chained filter predicate inference Closed/unmerged experiment, NOT merged/fixed or original-native0. COMPLETE original configured Darkreader source program and immutable1000-installed-package SDK retained; no source bodies/type bases projected or guessed. Exact source chrome.tabs.Tab/queryTabs/actualBooleanMV3 globals/first source disjunctive boolean filter/TabManagerState nested numeric-index registry/full original method/BOTH browser branches retained. Config-selected root imports used for historical harness and same-tree resolution guarded; genuine5.7.2 full original project auxiliary control passed separately. Exact PR parent/head source controls, deleted bot historical merge/main installations not recovered. Intrinsic object/no-priming early candidates produced0/0 and were REJECTED. Source first filter contextual priming is ESSENTIAL: final nine-line SDK-free reduction uses always-true first filter then original structured numeric-index truthiness filter;0/head2339/current0, removing ONLY first filter head0 and separate noUncheckedIndexedAccess:true head0. Original native THREE removed options(baseUrl/downlevelIteration5102,node105108). Removing them+bundler alone exposes77 current new-default-strict diagnostics, explicit old default strict:false (retaining original explicit noImplicitAny/strictNullChecks) leavesONE2307bareutils/platform from removed baseUrl; separate exact baseUrl-equivalent wildcard paths while preserving @plus route then full original native0. Keep all intermediate controls, not conflate compatibility0 with original native0. MUI identity6da12fd9f38384ef remains UNPROVED/unmapped here; corrected source is downstreamsort .name after tags.ignore filter, unrelated isPropertySignature theory rejected. No external SDK imports/declaration blobs enter final test suite. Independent integration reran complete configured source/native/candidate/control verifier, audited ALL1000 installed versions/resolved/SRI against actual source lock/manifest, and independently compiled the CRLF-normalized byte-identical suite test with both original compilers:0/headsole2339/current0. Exact2 Darkreader IDs only; MUI1 remains parent-owned and is NOT mapped. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60834#issuecomment-2569954457 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../chainedFilterPredicateInference.js | 18 ++++++++ .../chainedFilterPredicateInference.symbols | 37 +++++++++++++++ .../chainedFilterPredicateInference.types | 46 +++++++++++++++++++ .../chainedFilterPredicateInference.ts | 9 ++++ 4 files changed, 110 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.js create mode 100644 tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.types create mode 100644 tsc/testdata/tests/cases/compiler/chainedFilterPredicateInference.ts diff --git a/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.js b/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.js new file mode 100644 index 0000000000000..b971af38d2f15 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/chainedFilterPredicateInference.ts] //// + +//// [chainedFilterPredicateInference.ts] +declare const items: { id: number }[]; +declare const registry: { [id: number]: { [frame: number]: unknown } }; + +items + .filter(item => true) + .filter(item => !registry[item.id]) + .forEach(item => item.id); + + +//// [chainedFilterPredicateInference.js] +"use strict"; +items + .filter(item => true) + .filter(item => !registry[item.id]) + .forEach(item => item.id); diff --git a/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.symbols b/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.symbols new file mode 100644 index 0000000000000..66e4d84e0aacb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/chainedFilterPredicateInference.ts] //// + +=== chainedFilterPredicateInference.ts === +declare const items: { id: number }[]; +>items : Symbol(items, Decl(chainedFilterPredicateInference.ts, 0, 13)) +>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22)) + +declare const registry: { [id: number]: { [frame: number]: unknown } }; +>registry : Symbol(registry, Decl(chainedFilterPredicateInference.ts, 1, 13)) +>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 1, 27)) +>frame : Symbol(frame, Decl(chainedFilterPredicateInference.ts, 1, 43)) + +items +>items .filter(item => true) .filter(item => !registry[item.id]) .forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>items .filter(item => true) .filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>items .filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>items : Symbol(items, Decl(chainedFilterPredicateInference.ts, 0, 13)) + + .filter(item => true) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 4, 12)) + + .filter(item => !registry[item.id]) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 5, 12)) +>registry : Symbol(registry, Decl(chainedFilterPredicateInference.ts, 1, 13)) +>item.id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22)) +>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 5, 12)) +>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22)) + + .forEach(item => item.id); +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 6, 13)) +>item.id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22)) +>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 6, 13)) +>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22)) + diff --git a/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.types b/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.types new file mode 100644 index 0000000000000..43a34fcadf8fa --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/chainedFilterPredicateInference.types @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/chainedFilterPredicateInference.ts] //// + +=== chainedFilterPredicateInference.ts === +declare const items: { id: number }[]; +>items : { id: number; }[] +>id : number + +declare const registry: { [id: number]: { [frame: number]: unknown } }; +>registry : { [id: number]: { [frame: number]: unknown; }; } +>id : number +>frame : number + +items +>items .filter(item => true) .filter(item => !registry[item.id]) .forEach(item => item.id) : void +>items .filter(item => true) .filter(item => !registry[item.id]) .forEach : (callbackfn: (value: { id: number; }, index: number, array: { id: number; }[]) => void, thisArg?: any) => void +>items .filter(item => true) .filter(item => !registry[item.id]) : { id: number; }[] +>items .filter(item => true) .filter : { (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; } +>items .filter(item => true) : { id: number; }[] +>items .filter : { (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; } +>items : { id: number; }[] + + .filter(item => true) +>filter : { (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; } +>item => true : (item: { id: number; }) => true +>item : { id: number; } +>true : true + + .filter(item => !registry[item.id]) +>filter : { (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; } +>item => !registry[item.id] : (item: { id: number; }) => false +>item : { id: number; } +>!registry[item.id] : false +>registry[item.id] : { [frame: number]: unknown; } +>registry : { [id: number]: { [frame: number]: unknown; }; } +>item.id : number +>item : { id: number; } +>id : number + + .forEach(item => item.id); +>forEach : (callbackfn: (value: { id: number; }, index: number, array: { id: number; }[]) => void, thisArg?: any) => void +>item => item.id : (item: { id: number; }) => number +>item : { id: number; } +>item.id : number +>item : { id: number; } +>id : number + diff --git a/tsc/testdata/tests/cases/compiler/chainedFilterPredicateInference.ts b/tsc/testdata/tests/cases/compiler/chainedFilterPredicateInference.ts new file mode 100644 index 0000000000000..af002f71550c5 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/chainedFilterPredicateInference.ts @@ -0,0 +1,9 @@ +// @strict: true + +declare const items: { id: number }[]; +declare const registry: { [id: number]: { [frame: number]: unknown } }; + +items + .filter(item => true) + .filter(item => !registry[item.id]) + .forEach(item => item.id); From 16796f03a7503eae8dc109e5636f6093e645db5d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 17:33:09 -0700 Subject: [PATCH 065/116] Add historical coverage: object from entries branded template keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exact Refined GitHub FIVE identities only. Complete original source clone6c0493b9884e56b8065051ad786f2a38bb4a585f and immutable original npm SDK (808 actual physical versions/resolved/SRI,860 descriptors,52 original optional platform omissions) with actual @sindresorhus/tsconfig7.0.0 inherited semantic flags and BOTH entire original314-root programs/1201 loaded source files executed unchanged: before0→exact five7053 at original options-storage17/23/24(two columns) and options32. No declaration-only SDK surrogate or consumer body projection; entire original OptionsSyncPerDomain/OptionsSync declarations, actual original feature-data/snapshot JSON/rename JSON/global string&{feature:true} brand and SDK getAll routes retained. Original options defaults broad string index→branded feature-template index inspected with all five real key types. Experimental Object.entries also narrows FROM to37 concrete original rename keys, while TO remains string; unbranded literal keys never gain FeatureID brand. Broadening ONLY actual fromEntries call return to Record makes BOTH entire source programs0; canonical source restored in finally, gitdiff clean. SDK-free15-line test preserves actual brand, map/fromEntries, broad template lookup, branded callback string-concatenation and actual rename-entries/typeof/assignment routes: before0/headfive7053/current0; unbranded provider removes four prefix/literal errors but leaves concat-string7053, broad return removes all five. Existing objectFromEntries tests only construct literal/frozen/URLSearchParams/Map values, and added spread/additional-property forms lack this branded template-index/rename flow. ORIGINAL whole-source native retains one2578 at unrelated select-notifications67; not native0 or suppressed. Separate source-entry positive control preserves semantic flags and entire genuine globals/SDK, asserts getAll-not-any/actionUrl:string/feature:boolean with native0. No app/runtime/bot installation claim; scripts disabled. Source/SDK/JSON never enter suite. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../objectFromEntriesBrandedTemplateKeys.js | 27 ++++++ ...jectFromEntriesBrandedTemplateKeys.symbols | 57 +++++++++++++ ...objectFromEntriesBrandedTemplateKeys.types | 83 +++++++++++++++++++ .../objectFromEntriesBrandedTemplateKeys.ts | 15 ++++ 4 files changed, 182 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.types create mode 100644 tsc/testdata/tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.js b/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.js new file mode 100644 index 0000000000000..532bf75270587 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts] //// + +//// [objectFromEntriesBrandedTemplateKeys.ts] +type FeatureId = string & { feature: true }; +declare const featureIds: FeatureId[]; +const options = Object.fromEntries(featureIds.map(id => [`feature:${id}`, true])); +declare const featureName: string; + +options[`feature:${featureName}`]; +featureIds.filter(id => options["feature:" + id]); +for (const [from, to] of Object.entries({ oldFeature: "newFeature" })) { + if (typeof options[`feature:${from}`] === "boolean") { + options[`feature:${to}`] = options[`feature:${from}`]; + } +} + + +//// [objectFromEntriesBrandedTemplateKeys.js] +"use strict"; +const options = Object.fromEntries(featureIds.map(id => [`feature:${id}`, true])); +options[`feature:${featureName}`]; +featureIds.filter(id => options["feature:" + id]); +for (const [from, to] of Object.entries({ oldFeature: "newFeature" })) { + if (typeof options[`feature:${from}`] === "boolean") { + options[`feature:${to}`] = options[`feature:${from}`]; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.symbols b/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.symbols new file mode 100644 index 0000000000000..0eb819503b8b3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.symbols @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts] //// + +=== objectFromEntriesBrandedTemplateKeys.ts === +type FeatureId = string & { feature: true }; +>FeatureId : Symbol(FeatureId, Decl(objectFromEntriesBrandedTemplateKeys.ts, 0, 0)) +>feature : Symbol(feature, Decl(objectFromEntriesBrandedTemplateKeys.ts, 0, 27)) + +declare const featureIds: FeatureId[]; +>featureIds : Symbol(featureIds, Decl(objectFromEntriesBrandedTemplateKeys.ts, 1, 13)) +>FeatureId : Symbol(FeatureId, Decl(objectFromEntriesBrandedTemplateKeys.ts, 0, 0)) + +const options = Object.fromEntries(featureIds.map(id => [`feature:${id}`, true])); +>options : Symbol(options, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 5)) +>Object.fromEntries : Symbol(ObjectConstructor.fromEntries, Decl(lib.es2019.object.d.ts, --, --), Decl(lib.es2019.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>fromEntries : Symbol(ObjectConstructor.fromEntries, Decl(lib.es2019.object.d.ts, --, --), Decl(lib.es2019.object.d.ts, --, --)) +>featureIds.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>featureIds : Symbol(featureIds, Decl(objectFromEntriesBrandedTemplateKeys.ts, 1, 13)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>id : Symbol(id, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 50)) +>id : Symbol(id, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 50)) + +declare const featureName: string; +>featureName : Symbol(featureName, Decl(objectFromEntriesBrandedTemplateKeys.ts, 3, 13)) + +options[`feature:${featureName}`]; +>options : Symbol(options, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 5)) +>featureName : Symbol(featureName, Decl(objectFromEntriesBrandedTemplateKeys.ts, 3, 13)) + +featureIds.filter(id => options["feature:" + id]); +>featureIds.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>featureIds : Symbol(featureIds, Decl(objectFromEntriesBrandedTemplateKeys.ts, 1, 13)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>id : Symbol(id, Decl(objectFromEntriesBrandedTemplateKeys.ts, 6, 18)) +>options : Symbol(options, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 5)) +>id : Symbol(id, Decl(objectFromEntriesBrandedTemplateKeys.ts, 6, 18)) + +for (const [from, to] of Object.entries({ oldFeature: "newFeature" })) { +>from : Symbol(from, Decl(objectFromEntriesBrandedTemplateKeys.ts, 7, 12)) +>to : Symbol(to, Decl(objectFromEntriesBrandedTemplateKeys.ts, 7, 17)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>oldFeature : Symbol(oldFeature, Decl(objectFromEntriesBrandedTemplateKeys.ts, 7, 41)) + + if (typeof options[`feature:${from}`] === "boolean") { +>options : Symbol(options, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 5)) +>from : Symbol(from, Decl(objectFromEntriesBrandedTemplateKeys.ts, 7, 12)) + + options[`feature:${to}`] = options[`feature:${from}`]; +>options : Symbol(options, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 5)) +>to : Symbol(to, Decl(objectFromEntriesBrandedTemplateKeys.ts, 7, 17)) +>options : Symbol(options, Decl(objectFromEntriesBrandedTemplateKeys.ts, 2, 5)) +>from : Symbol(from, Decl(objectFromEntriesBrandedTemplateKeys.ts, 7, 12)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.types b/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.types new file mode 100644 index 0000000000000..7a209ef2d4ee0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectFromEntriesBrandedTemplateKeys.types @@ -0,0 +1,83 @@ +//// [tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts] //// + +=== objectFromEntriesBrandedTemplateKeys.ts === +type FeatureId = string & { feature: true }; +>FeatureId : FeatureId +>feature : true +>true : true + +declare const featureIds: FeatureId[]; +>featureIds : FeatureId[] + +const options = Object.fromEntries(featureIds.map(id => [`feature:${id}`, true])); +>options : { [k: string]: boolean; } +>Object.fromEntries(featureIds.map(id => [`feature:${id}`, true])) : { [k: string]: boolean; } +>Object.fromEntries : { (entries: Iterable): { [k: string]: T; }; (entries: Iterable): any; } +>Object : ObjectConstructor +>fromEntries : { (entries: Iterable): { [k: string]: T; }; (entries: Iterable): any; } +>featureIds.map(id => [`feature:${id}`, true]) : [string, boolean][] +>featureIds.map : (callbackfn: (value: FeatureId, index: number, array: FeatureId[]) => U, thisArg?: any) => U[] +>featureIds : FeatureId[] +>map : (callbackfn: (value: FeatureId, index: number, array: FeatureId[]) => U, thisArg?: any) => U[] +>id => [`feature:${id}`, true] : (id: FeatureId) => [string, boolean] +>id : FeatureId +>[`feature:${id}`, true] : [string, true] +>`feature:${id}` : string +>id : FeatureId +>true : true + +declare const featureName: string; +>featureName : string + +options[`feature:${featureName}`]; +>options[`feature:${featureName}`] : boolean +>options : { [k: string]: boolean; } +>`feature:${featureName}` : `feature:${string}` +>featureName : string + +featureIds.filter(id => options["feature:" + id]); +>featureIds.filter(id => options["feature:" + id]) : FeatureId[] +>featureIds.filter : { (predicate: (value: FeatureId, index: number, array: FeatureId[]) => value is S, thisArg?: any): S[]; (predicate: (value: FeatureId, index: number, array: FeatureId[]) => unknown, thisArg?: any): FeatureId[]; } +>featureIds : FeatureId[] +>filter : { (predicate: (value: FeatureId, index: number, array: FeatureId[]) => value is S, thisArg?: any): S[]; (predicate: (value: FeatureId, index: number, array: FeatureId[]) => unknown, thisArg?: any): FeatureId[]; } +>id => options["feature:" + id] : (id: FeatureId) => boolean +>id : FeatureId +>options["feature:" + id] : boolean +>options : { [k: string]: boolean; } +>"feature:" + id : string +>"feature:" : "feature:" +>id : FeatureId + +for (const [from, to] of Object.entries({ oldFeature: "newFeature" })) { +>from : string +>to : string +>Object.entries({ oldFeature: "newFeature" }) : [string, string][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>{ oldFeature: "newFeature" } : { oldFeature: string; } +>oldFeature : string +>"newFeature" : "newFeature" + + if (typeof options[`feature:${from}`] === "boolean") { +>typeof options[`feature:${from}`] === "boolean" : boolean +>typeof options[`feature:${from}`] : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>options[`feature:${from}`] : boolean +>options : { [k: string]: boolean; } +>`feature:${from}` : `feature:${string}` +>from : string +>"boolean" : "boolean" + + options[`feature:${to}`] = options[`feature:${from}`]; +>options[`feature:${to}`] = options[`feature:${from}`] : boolean +>options[`feature:${to}`] : boolean +>options : { [k: string]: boolean; } +>`feature:${to}` : `feature:${string}` +>to : string +>options[`feature:${from}`] : boolean +>options : { [k: string]: boolean; } +>`feature:${from}` : `feature:${string}` +>from : string + } +} + diff --git a/tsc/testdata/tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts b/tsc/testdata/tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts new file mode 100644 index 0000000000000..b933e19b43053 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectFromEntriesBrandedTemplateKeys.ts @@ -0,0 +1,15 @@ +// @target: es2019 +// @strict: true + +type FeatureId = string & { feature: true }; +declare const featureIds: FeatureId[]; +const options = Object.fromEntries(featureIds.map(id => [`feature:${id}`, true])); +declare const featureName: string; + +options[`feature:${featureName}`]; +featureIds.filter(id => options["feature:" + id]); +for (const [from, to] of Object.entries({ oldFeature: "newFeature" })) { + if (typeof options[`feature:${from}`] === "boolean") { + options[`feature:${to}`] = options[`feature:${from}`]; + } +} From d4b27d712664be5b4c624c5f0aff5a6e3151bf60 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 17:57:58 -0700 Subject: [PATCH 066/116] Add historical coverage: contextual return recursive pattern arguments Complete pinned ts-pattern tests/source and genuine frozen649-package original npm SDK: exact479285d0 parent0 ->77331a98 head two unused2578 at403/417 plus separate when2344. This SDK-free optional/intersection recursive-pattern case independently gives0 ->2578x2/current0; dispensable const type-parameter modifiers removed. Closed/unmerged experiment; exact original parent/head, not the later 2026 retained merge or recovered bot installation. All original source-config test roots and source modules use the complete genuine frozen SDK; no hand-written Match/input contract in the authoritative full program. Private source-import projection is only an intermediate causal route; final kernels are SDK-free and need child independent coverage audit before disposition. Full original native reports removed options; supported options alone additionally lack automatic Jest/Node global discovery. Separate explicit installed-type profile still has ONE unrelated distribute-unions.test.ts240 equality assertion; never original/native-full-program zero. Kernel callback genuine string/not-any/not-never native controls pass; source annotation-only control produces 2769 and is retained as rejected, while explicit source overload type arguments remove ONLY the callback regression. Do not map the already-accepted github/docs PR61913 identity or any other diagnostics. Integrated kernels omit dispensable const type-parameter modifiers; both independently rerun before/head/current. Literal optional/intersection forms share one scenario; array-creator callback losing string to unknown is a distinct second scenario. Full original native 5102+5108, supported explicit installed-type program retains one unrelated distribute-unions2344; not mapped. Existing github/docs identity remains untouched. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61913#issuecomment-2994475582 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ntextualReturnRecursivePatternArguments.js | 32 ++++++ ...ualReturnRecursivePatternArguments.symbols | 98 +++++++++++++++++++ ...xtualReturnRecursivePatternArguments.types | 61 ++++++++++++ ...ntextualReturnRecursivePatternArguments.ts | 19 ++++ 4 files changed, 210 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.js create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.types create mode 100644 tsc/testdata/tests/cases/compiler/contextualReturnRecursivePatternArguments.ts diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.js b/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.js new file mode 100644 index 0000000000000..b027eee9db1d2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/contextualReturnRecursivePatternArguments.ts] //// + +//// [contextualReturnRecursivePatternArguments.ts] +interface Matcher { + matcher(): { match(value: Input): boolean; pattern?: Pattern }; +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +declare function union, ...Pattern[]]>(...patterns: Patterns): Matcher; +declare function optional>(value: Value): Matcher; +declare function intersection, ...Pattern[]]>(...values: Values): Matcher; +declare function accept>(value: Value): void; + +accept(optional({ + // @ts-expect-error + type: union("oops"), +})); +accept(intersection({ + // @ts-expect-error + type: union("oops"), +})); + + +//// [contextualReturnRecursivePatternArguments.js] +"use strict"; +accept(optional({ + // @ts-expect-error + type: union("oops"), +})); +accept(intersection({ + // @ts-expect-error + type: union("oops"), +})); diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.symbols b/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.symbols new file mode 100644 index 0000000000000..9bda87af09993 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.symbols @@ -0,0 +1,98 @@ +//// [tests/cases/compiler/contextualReturnRecursivePatternArguments.ts] //// + +=== contextualReturnRecursivePatternArguments.ts === +interface Matcher { +>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 0, 18)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 0, 24)) + + matcher(): { match(value: Input): boolean; pattern?: Pattern }; +>matcher : Symbol(Matcher.matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 45)) +>match : Symbol(match, Decl(contextualReturnRecursivePatternArguments.ts, 1, 16)) +>value : Symbol(value, Decl(contextualReturnRecursivePatternArguments.ts, 1, 23)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 0, 18)) +>pattern : Symbol(pattern, Decl(contextualReturnRecursivePatternArguments.ts, 1, 46)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 0, 24)) +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13)) +>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13)) +>Key : Symbol(Key, Decl(contextualReturnRecursivePatternArguments.ts, 3, 50)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13)) +>Key : Symbol(Key, Decl(contextualReturnRecursivePatternArguments.ts, 3, 50)) + +declare function union, ...Pattern[]]>(...patterns: Patterns): Matcher; +>union : Symbol(union, Decl(contextualReturnRecursivePatternArguments.ts, 3, 94)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23)) +>Patterns : Symbol(Patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 29)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23)) +>patterns : Symbol(patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 95)) +>Patterns : Symbol(Patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 29)) +>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23)) +>Patterns : Symbol(Patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 29)) + +declare function optional>(value: Value): Matcher; +>optional : Symbol(optional, Decl(contextualReturnRecursivePatternArguments.ts, 4, 144)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26)) +>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 32)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26)) +>value : Symbol(value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 97)) +>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 32)) +>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26)) +>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 32)) + +declare function intersection, ...Pattern[]]>(...values: Values): Matcher; +>intersection : Symbol(intersection, Decl(contextualReturnRecursivePatternArguments.ts, 5, 134)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30)) +>Values : Symbol(Values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 36)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30)) +>values : Symbol(values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 100)) +>Values : Symbol(Values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 36)) +>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30)) +>Values : Symbol(Values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 36)) + +declare function accept>(value: Value): void; +>accept : Symbol(accept, Decl(contextualReturnRecursivePatternArguments.ts, 6, 143)) +>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 7, 24)) +>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1)) +>type : Symbol(type, Decl(contextualReturnRecursivePatternArguments.ts, 7, 47)) +>value : Symbol(value, Decl(contextualReturnRecursivePatternArguments.ts, 7, 68)) +>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 7, 24)) + +accept(optional({ +>accept : Symbol(accept, Decl(contextualReturnRecursivePatternArguments.ts, 6, 143)) +>optional : Symbol(optional, Decl(contextualReturnRecursivePatternArguments.ts, 4, 144)) + + // @ts-expect-error + type: union("oops"), +>type : Symbol(type, Decl(contextualReturnRecursivePatternArguments.ts, 9, 17)) +>union : Symbol(union, Decl(contextualReturnRecursivePatternArguments.ts, 3, 94)) + +})); +accept(intersection({ +>accept : Symbol(accept, Decl(contextualReturnRecursivePatternArguments.ts, 6, 143)) +>intersection : Symbol(intersection, Decl(contextualReturnRecursivePatternArguments.ts, 5, 134)) + + // @ts-expect-error + type: union("oops"), +>type : Symbol(type, Decl(contextualReturnRecursivePatternArguments.ts, 13, 21)) +>union : Symbol(union, Decl(contextualReturnRecursivePatternArguments.ts, 3, 94)) + +})); + diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.types b/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.types new file mode 100644 index 0000000000000..d0b3ccfc95aa5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnRecursivePatternArguments.types @@ -0,0 +1,61 @@ +//// [tests/cases/compiler/contextualReturnRecursivePatternArguments.ts] //// + +=== contextualReturnRecursivePatternArguments.ts === +interface Matcher { + matcher(): { match(value: Input): boolean; pattern?: Pattern }; +>matcher : () => { match(value: Input): boolean; pattern?: Pattern; } +>match : (value: Input) => boolean +>value : Input +>pattern : Pattern | undefined +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +>Pattern : Pattern + +declare function union, ...Pattern[]]>(...patterns: Patterns): Matcher; +>union : , ...Pattern[]]>(...patterns: Patterns) => Matcher +>patterns : Patterns + +declare function optional>(value: Value): Matcher; +>optional : >(value: Value) => Matcher +>value : Value + +declare function intersection, ...Pattern[]]>(...values: Values): Matcher; +>intersection : , ...Pattern[]]>(...values: Values) => Matcher +>values : Values + +declare function accept>(value: Value): void; +>accept : >(value: Value) => void +>type : "a" | "b" +>value : Value + +accept(optional({ +>accept(optional({ // @ts-expect-error type: union("oops"),})) : void +>accept : >(value: Value) => void +>optional({ // @ts-expect-error type: union("oops"),}) : Matcher, ...Pattern<"a" | "b">[]]>; }> +>optional : >(value: Value) => Matcher +>{ // @ts-expect-error type: union("oops"),} : { type: Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>; } + + // @ts-expect-error + type: union("oops"), +>type : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]> +>union("oops") : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]> +>union : , ...Pattern[]]>(...patterns: Patterns) => Matcher +>"oops" : "oops" + +})); +accept(intersection({ +>accept(intersection({ // @ts-expect-error type: union("oops"),})) : void +>accept : >(value: Value) => void +>intersection({ // @ts-expect-error type: union("oops"),}) : Matcher, ...Pattern<"a" | "b">[]]>; }]> +>intersection : , ...Pattern[]]>(...values: Values) => Matcher +>{ // @ts-expect-error type: union("oops"),} : { type: Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>; } + + // @ts-expect-error + type: union("oops"), +>type : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]> +>union("oops") : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]> +>union : , ...Pattern[]]>(...patterns: Patterns) => Matcher +>"oops" : "oops" + +})); + diff --git a/tsc/testdata/tests/cases/compiler/contextualReturnRecursivePatternArguments.ts b/tsc/testdata/tests/cases/compiler/contextualReturnRecursivePatternArguments.ts new file mode 100644 index 0000000000000..3509850c6573a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualReturnRecursivePatternArguments.ts @@ -0,0 +1,19 @@ +// @strict: true + +interface Matcher { + matcher(): { match(value: Input): boolean; pattern?: Pattern }; +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +declare function union, ...Pattern[]]>(...patterns: Patterns): Matcher; +declare function optional>(value: Value): Matcher; +declare function intersection, ...Pattern[]]>(...values: Values): Matcher; +declare function accept>(value: Value): void; + +accept(optional({ + // @ts-expect-error + type: union("oops"), +})); +accept(intersection({ + // @ts-expect-error + type: union("oops"), +})); From 034099034551c02320557376ef4f2f8ec1b2c9b7 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 17:58:07 -0700 Subject: [PATCH 067/116] Add historical coverage: contextual return array pattern callback Complete pinned ts-pattern original callback/Equal assertion218 changes2344 under exact479285d0/77331a98 experiment. SDK-free recursive array creator preserves callbackstring before ->unknown head, demonstrated by string assignment2322; current0 plus genuine not-any/not-never/string controls. Removing only array creator gives0/0. Closed/unmerged experiment; exact original parent/head, not the later 2026 retained merge or recovered bot installation. All original source-config test roots and source modules use the complete genuine frozen SDK; no hand-written Match/input contract in the authoritative full program. Private source-import projection is only an intermediate causal route; final kernels are SDK-free and need child independent coverage audit before disposition. Full original native reports removed options; supported options alone additionally lack automatic Jest/Node global discovery. Separate explicit installed-type profile still has ONE unrelated distribute-unions.test.ts240 equality assertion; never original/native-full-program zero. Kernel callback genuine string/not-any/not-never native controls pass; source annotation-only control produces 2769 and is retained as rejected, while explicit source overload type arguments remove ONLY the callback regression. Do not map the already-accepted github/docs PR61913 identity or any other diagnostics. Integrated kernels omit dispensable const type-parameter modifiers; both independently rerun before/head/current. Literal optional/intersection forms share one scenario; array-creator callback losing string to unknown is a distinct second scenario. Full original native 5102+5108, supported explicit installed-type program retains one unrelated distribute-unions2344; not mapped. Existing github/docs identity remains untouched. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61913#issuecomment-2994475582 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../contextualReturnArrayPatternCallback.js | 32 +++++++ ...ntextualReturnArrayPatternCallback.symbols | 89 +++++++++++++++++++ ...contextualReturnArrayPatternCallback.types | 60 +++++++++++++ .../contextualReturnArrayPatternCallback.ts | 19 ++++ 4 files changed, 200 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.js create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.types create mode 100644 tsc/testdata/tests/cases/compiler/contextualReturnArrayPatternCallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.js b/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.js new file mode 100644 index 0000000000000..6772baec879f7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/contextualReturnArrayPatternCallback.ts] //// + +//// [contextualReturnArrayPatternCallback.ts] +interface Matcher { + matcher(): { match(value: Input): boolean; value?: Value }; +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +type ArrayElement = Input extends readonly (infer Value)[] ? Value : unknown; +declare function array>>(value: Value): Matcher; +declare function when unknown>(callback: Callback): Matcher; +declare function accept>(value: Value): void; + +accept({ + list: array({ + prop: when(value => { + const text: string = value; + return true; + }), + }), +}); + + +//// [contextualReturnArrayPatternCallback.js] +"use strict"; +accept({ + list: array({ + prop: when(value => { + const text = value; + return true; + }), + }), +}); diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.symbols b/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.symbols new file mode 100644 index 0000000000000..2e6faa18727fd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.symbols @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/contextualReturnArrayPatternCallback.ts] //// + +=== contextualReturnArrayPatternCallback.ts === +interface Matcher { +>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 0, 18)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 0, 24)) + + matcher(): { match(value: Input): boolean; value?: Value }; +>matcher : Symbol(Matcher.matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 43)) +>match : Symbol(match, Decl(contextualReturnArrayPatternCallback.ts, 1, 16)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 1, 23)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 0, 18)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 1, 46)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 0, 24)) +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13)) +>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13)) +>Key : Symbol(Key, Decl(contextualReturnArrayPatternCallback.ts, 3, 50)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13)) +>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13)) +>Key : Symbol(Key, Decl(contextualReturnArrayPatternCallback.ts, 3, 50)) + +type ArrayElement = Input extends readonly (infer Value)[] ? Value : unknown; +>ArrayElement : Symbol(ArrayElement, Decl(contextualReturnArrayPatternCallback.ts, 3, 94)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 4, 18)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 4, 18)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 4, 56)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 4, 56)) + +declare function array>>(value: Value): Matcher; +>array : Symbol(array, Decl(contextualReturnArrayPatternCallback.ts, 4, 84)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 5, 23)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 5, 29)) +>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1)) +>ArrayElement : Symbol(ArrayElement, Decl(contextualReturnArrayPatternCallback.ts, 3, 94)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 5, 23)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 5, 74)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 5, 29)) +>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 5, 23)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 5, 29)) + +declare function when unknown>(callback: Callback): Matcher; +>when : Symbol(when, Decl(contextualReturnArrayPatternCallback.ts, 5, 111)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 6, 22)) +>Callback : Symbol(Callback, Decl(contextualReturnArrayPatternCallback.ts, 6, 28)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 6, 47)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 6, 22)) +>callback : Symbol(callback, Decl(contextualReturnArrayPatternCallback.ts, 6, 73)) +>Callback : Symbol(Callback, Decl(contextualReturnArrayPatternCallback.ts, 6, 28)) +>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0)) +>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 6, 22)) + +declare function accept>(value: Value): void; +>accept : Symbol(accept, Decl(contextualReturnArrayPatternCallback.ts, 6, 109)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 7, 24)) +>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1)) +>list : Symbol(list, Decl(contextualReturnArrayPatternCallback.ts, 7, 47)) +>prop : Symbol(prop, Decl(contextualReturnArrayPatternCallback.ts, 7, 55)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 7, 77)) +>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 7, 24)) + +accept({ +>accept : Symbol(accept, Decl(contextualReturnArrayPatternCallback.ts, 6, 109)) + + list: array({ +>list : Symbol(list, Decl(contextualReturnArrayPatternCallback.ts, 9, 8)) +>array : Symbol(array, Decl(contextualReturnArrayPatternCallback.ts, 4, 84)) + + prop: when(value => { +>prop : Symbol(prop, Decl(contextualReturnArrayPatternCallback.ts, 10, 17)) +>when : Symbol(when, Decl(contextualReturnArrayPatternCallback.ts, 5, 111)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 11, 19)) + + const text: string = value; +>text : Symbol(text, Decl(contextualReturnArrayPatternCallback.ts, 12, 17)) +>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 11, 19)) + + return true; + }), + }), +}); + diff --git a/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.types b/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.types new file mode 100644 index 0000000000000..8ae0e4c69acc3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualReturnArrayPatternCallback.types @@ -0,0 +1,60 @@ +//// [tests/cases/compiler/contextualReturnArrayPatternCallback.ts] //// + +=== contextualReturnArrayPatternCallback.ts === +interface Matcher { + matcher(): { match(value: Input): boolean; value?: Value }; +>matcher : () => { match(value: Input): boolean; value?: Value; } +>match : (value: Input) => boolean +>value : Input +>value : Value | undefined +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +>Pattern : Pattern + +type ArrayElement = Input extends readonly (infer Value)[] ? Value : unknown; +>ArrayElement : ArrayElement + +declare function array>>(value: Value): Matcher; +>array : >>(value: Value) => Matcher +>value : Value + +declare function when unknown>(callback: Callback): Matcher; +>when : unknown>(callback: Callback) => Matcher +>value : Input +>callback : Callback + +declare function accept>(value: Value): void; +>accept : >(value: Value) => void +>list : { prop: string; }[] +>prop : string +>value : Value + +accept({ +>accept({ list: array({ prop: when(value => { const text: string = value; return true; }), }),}) : void +>accept : >(value: Value) => void +>{ list: array({ prop: when(value => { const text: string = value; return true; }), }),} : { list: Matcher<{ prop: string; }[], { prop: Matcher; }>; } + + list: array({ +>list : Matcher<{ prop: string; }[], { prop: Matcher; }> +>array({ prop: when(value => { const text: string = value; return true; }), }) : Matcher<{ prop: string; }[], { prop: Matcher; }> +>array : >>(value: Value) => Matcher +>{ prop: when(value => { const text: string = value; return true; }), } : { prop: Matcher; } + + prop: when(value => { +>prop : Matcher +>when(value => { const text: string = value; return true; }) : Matcher +>when : unknown>(callback: Callback) => Matcher +>value => { const text: string = value; return true; } : (value: string) => boolean +>value : string + + const text: string = value; +>text : string +>value : string + + return true; +>true : true + + }), + }), +}); + diff --git a/tsc/testdata/tests/cases/compiler/contextualReturnArrayPatternCallback.ts b/tsc/testdata/tests/cases/compiler/contextualReturnArrayPatternCallback.ts new file mode 100644 index 0000000000000..04519047a9dc7 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualReturnArrayPatternCallback.ts @@ -0,0 +1,19 @@ +// @strict: true + +interface Matcher { + matcher(): { match(value: Input): boolean; value?: Value }; +} +type Pattern = Input | Matcher | { [Key in keyof Input]?: Pattern }; +type ArrayElement = Input extends readonly (infer Value)[] ? Value : unknown; +declare function array>>(value: Value): Matcher; +declare function when unknown>(callback: Callback): Matcher; +declare function accept>(value: Value): void; + +accept({ + list: array({ + prop: when(value => { + const text: string = value; + return true; + }), + }), +}); From a1e41cdd9249483a77d95dace25aef259187409a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 18:08:30 -0700 Subject: [PATCH 068/116] Add historical coverage: object entries map broad key lookup Selected source SDK closure, not the whole original application install. Complete original LangCode/data/Config/map/getLangName ASTs retained; unrelated language runtime helpers projected away. Exact original semantic flags/types/typeRoots preserved. Config root discovery projected to the actual original Vite import, retaining genuine Vite-to-Node ambient library discovery; no invented lib or types override. Full original Vite build bodies/vitest and unrelated app/config roots are not claimed. Actual explicit source LangCode union, not a fromEntries/keyof-derived alias. Original source0/head sole2345@99; genuine Map becomes Map. Original native sole5108 retained; separately changing only unsupported node10 resolution to bundler gives source0, genuine SDK/config/map-not-any and string controls0. Removing only actual Vite config import loses Node's real ES2020 library discovery and yields2550+7031x2+2322 in BOTH phases, retained as rejected incomplete discovery, never repaired with invented libs/types. SDK-free map callback and object-valued record were independently proved dispensable; final direct Map(entries).get(string) preserves the actual key-lookup incompatibility. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../objectEntriesMapBroadKeyLookup.js | 12 ++++++++++ .../objectEntriesMapBroadKeyLookup.symbols | 20 +++++++++++++++++ .../objectEntriesMapBroadKeyLookup.types | 22 +++++++++++++++++++ .../objectEntriesMapBroadKeyLookup.ts | 7 ++++++ 4 files changed, 61 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.types create mode 100644 tsc/testdata/tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.js b/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.js new file mode 100644 index 0000000000000..ef82e6f2e88fc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts] //// + +//// [objectEntriesMapBroadKeyLookup.ts] +declare const languages: Record<"en" | "fr", string>; +declare const language: string; + +new Map(Object.entries(languages)).get(language); + + +//// [objectEntriesMapBroadKeyLookup.js] +"use strict"; +new Map(Object.entries(languages)).get(language); diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.symbols b/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.symbols new file mode 100644 index 0000000000000..9977a864a467a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts] //// + +=== objectEntriesMapBroadKeyLookup.ts === +declare const languages: Record<"en" | "fr", string>; +>languages : Symbol(languages, Decl(objectEntriesMapBroadKeyLookup.ts, 0, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +declare const language: string; +>language : Symbol(language, Decl(objectEntriesMapBroadKeyLookup.ts, 1, 13)) + +new Map(Object.entries(languages)).get(language); +>new Map(Object.entries(languages)).get : Symbol(Map.get, Decl(lib.es2015.collection.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>languages : Symbol(languages, Decl(objectEntriesMapBroadKeyLookup.ts, 0, 13)) +>get : Symbol(Map.get, Decl(lib.es2015.collection.d.ts, --, --)) +>language : Symbol(language, Decl(objectEntriesMapBroadKeyLookup.ts, 1, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.types b/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.types new file mode 100644 index 0000000000000..c650634a3e02b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesMapBroadKeyLookup.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts] //// + +=== objectEntriesMapBroadKeyLookup.ts === +declare const languages: Record<"en" | "fr", string>; +>languages : Record<"en" | "fr", string> + +declare const language: string; +>language : string + +new Map(Object.entries(languages)).get(language); +>new Map(Object.entries(languages)).get(language) : string | undefined +>new Map(Object.entries(languages)).get : (key: string) => string | undefined +>new Map(Object.entries(languages)) : Map +>Map : MapConstructor +>Object.entries(languages) : [string, string][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>languages : Record<"en" | "fr", string> +>get : (key: string) => string | undefined +>language : string + diff --git a/tsc/testdata/tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts b/tsc/testdata/tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts new file mode 100644 index 0000000000000..8276d8e35f425 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectEntriesMapBroadKeyLookup.ts @@ -0,0 +1,7 @@ +// @target: es2017 +// @strict: true + +declare const languages: Record<"en" | "fr", string>; +declare const language: string; + +new Map(Object.entries(languages)).get(language); From 1329942e51af1aebb5c86de82b8c8ceca7cc90b5 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 18:58:04 -0700 Subject: [PATCH 069/116] Add historical coverage: object entries symbol value arity Three complete original db.ts files/config semantic flags and genuine original Next envs with selected independent frozen original app Yarn locks, not full app roots/builds or recovered bot installation. Original tree proves THREE real locks (agent's no-lock/range-only0.16.2 assertion rejected); actual MSW data0.16.1 supplies four ModelAPI0-1 create signatures plus unique-symbol-only Database2-3 create. Exact original PR-parent/head source0/2554@93 or94, tuple keys remainstring while only value gains Database. Source-derived Pick removing only symbol members makes all6 matrices clean; ordinary-string-member minimal control failsBOTH, omitted-symbol and string-key view0/0. Original native Vite5102(baseUrl), Next both5108(node10) remain; separate Vite removal-only and Next bundler-only source plus genuine model/entity/string/actual two-argument private Database controls0. Existing18 files/all20 option profiles source-audited/executed: the later no-crash regression crashes both historical compilers and is explicitly rejected, not counted as symbol coverage; DeepPromised's Object.values unchanged. No existing concrete symbol-only extra create-signature route found. SDK-free ten nonblank-line kernel0/2554/current0, exact source arity0-1 to2-3 and current not-any/not-never/one-argument signature preserved. No external suite imports, SDK declarations or implementation changes. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/objectEntriesSymbolValueArity.js | 19 +++++++++ .../objectEntriesSymbolValueArity.symbols | 37 +++++++++++++++++ .../objectEntriesSymbolValueArity.types | 40 +++++++++++++++++++ .../compiler/objectEntriesSymbolValueArity.ts | 12 ++++++ 4 files changed, 108 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.types create mode 100644 tsc/testdata/tests/cases/compiler/objectEntriesSymbolValueArity.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.js b/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.js new file mode 100644 index 0000000000000..23bd0e230e6bd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/objectEntriesSymbolValueArity.ts] //// + +//// [objectEntriesSymbolValueArity.ts] +declare const database: unique symbol; +declare const models: { + user: { create(entity?: object): void }; + [database]: { create(name: string, entity: object, id?: string): void }; +}; + +for (const [, model] of Object.entries(models)) { + model.create({}); +} + + +//// [objectEntriesSymbolValueArity.js] +"use strict"; +for (const [, model] of Object.entries(models)) { + model.create({}); +} diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.symbols b/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.symbols new file mode 100644 index 0000000000000..afe2682939b83 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/objectEntriesSymbolValueArity.ts] //// + +=== objectEntriesSymbolValueArity.ts === +declare const database: unique symbol; +>database : Symbol(database, Decl(objectEntriesSymbolValueArity.ts, 0, 13)) + +declare const models: { +>models : Symbol(models, Decl(objectEntriesSymbolValueArity.ts, 1, 13)) + + user: { create(entity?: object): void }; +>user : Symbol(user, Decl(objectEntriesSymbolValueArity.ts, 1, 23)) +>create : Symbol(create, Decl(objectEntriesSymbolValueArity.ts, 2, 11)) +>entity : Symbol(entity, Decl(objectEntriesSymbolValueArity.ts, 2, 19)) + + [database]: { create(name: string, entity: object, id?: string): void }; +>[database] : Symbol([database], Decl(objectEntriesSymbolValueArity.ts, 2, 44)) +>database : Symbol(database, Decl(objectEntriesSymbolValueArity.ts, 0, 13)) +>create : Symbol(create, Decl(objectEntriesSymbolValueArity.ts, 3, 17)) +>name : Symbol(name, Decl(objectEntriesSymbolValueArity.ts, 3, 25)) +>entity : Symbol(entity, Decl(objectEntriesSymbolValueArity.ts, 3, 38)) +>id : Symbol(id, Decl(objectEntriesSymbolValueArity.ts, 3, 54)) + +}; + +for (const [, model] of Object.entries(models)) { +>model : Symbol(model, Decl(objectEntriesSymbolValueArity.ts, 6, 13)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>models : Symbol(models, Decl(objectEntriesSymbolValueArity.ts, 1, 13)) + + model.create({}); +>model.create : Symbol(create, Decl(objectEntriesSymbolValueArity.ts, 2, 11)) +>model : Symbol(model, Decl(objectEntriesSymbolValueArity.ts, 6, 13)) +>create : Symbol(create, Decl(objectEntriesSymbolValueArity.ts, 2, 11)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.types b/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.types new file mode 100644 index 0000000000000..2c6c28c5ee395 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesSymbolValueArity.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/objectEntriesSymbolValueArity.ts] //// + +=== objectEntriesSymbolValueArity.ts === +declare const database: unique symbol; +>database : unique symbol + +declare const models: { +>models : { user: { create(entity?: object): void; }; [database]: { create(name: string, entity: object, id?: string): void; }; } + + user: { create(entity?: object): void }; +>user : { create(entity?: object): void; } +>create : (entity?: object) => void +>entity : object | undefined + + [database]: { create(name: string, entity: object, id?: string): void }; +>[database] : { create(name: string, entity: object, id?: string): void; } +>database : unique symbol +>create : (name: string, entity: object, id?: string) => void +>name : string +>entity : object +>id : string | undefined + +}; + +for (const [, model] of Object.entries(models)) { +>model : { create(entity?: object): void; } +>Object.entries(models) : [string, { create(entity?: object): void; }][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>models : { user: { create(entity?: object): void; }; [database]: { create(name: string, entity: object, id?: string): void; }; } + + model.create({}); +>model.create({}) : void +>model.create : (entity?: object) => void +>model : { create(entity?: object): void; } +>create : (entity?: object) => void +>{} : {} +} + diff --git a/tsc/testdata/tests/cases/compiler/objectEntriesSymbolValueArity.ts b/tsc/testdata/tests/cases/compiler/objectEntriesSymbolValueArity.ts new file mode 100644 index 0000000000000..8992e3e899ccd --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectEntriesSymbolValueArity.ts @@ -0,0 +1,12 @@ +// @strict: true +// @target: es2017 + +declare const database: unique symbol; +declare const models: { + user: { create(entity?: object): void }; + [database]: { create(name: string, entity: object, id?: string): void }; +}; + +for (const [, model] of Object.entries(models)) { + model.create({}); +} From 7612d5ad7a61b5c3aa053686a8124cbd6963098a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 19:27:18 -0700 Subject: [PATCH 070/116] Add historical coverage: new target undefined equality Exact closed/unmerged incomplete PR60433 equality experiment, placeholder TS2870 (not nullish-coalescing syntax). Complete original FormatJS seven-file Segmenter BUILD source/generated CLDR/own workspace route and selected original tslib2.8.1, versus complete NodeGuards/helper projection with selected original ESTree0.0.51 SRI, not full monorepo/Bazel or four Obfuscator projects/bot installs. Original FormatJS native5102baseUrl+5108ES5 and projected NodeGuards native5108node10 retained; separate supported source profiles pass. Minimal integrated cases preserve current accepted equality syntax, not an assertion that the source logical-not predicate is correct. Genuine source negation comparison is an intentional candidate tightening; class new.target guard is reachable under original ES5 downlevel only for a null-prototype receiver, not an ordinary {} receiver. Current supported ES2015 tests do not claim native ES5 support. Existing null/undefined comparison fallout does not exercise these two operand forms; existing new.target nullish-coalescing is unchanged across historical snapshots. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60433#issuecomment-2460603054 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/newTargetUndefinedEquality.js | 18 ++++++++++++++++++ .../newTargetUndefinedEquality.symbols | 15 +++++++++++++++ .../compiler/newTargetUndefinedEquality.types | 18 ++++++++++++++++++ .../compiler/newTargetUndefinedEquality.ts | 8 ++++++++ 4 files changed, 59 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.js create mode 100644 tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.types create mode 100644 tsc/testdata/tests/cases/compiler/newTargetUndefinedEquality.ts diff --git a/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.js b/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.js new file mode 100644 index 0000000000000..f5c34dd882fb4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/newTargetUndefinedEquality.ts] //// + +//// [newTargetUndefinedEquality.ts] +class ConstructorGuard { + constructor() { + if (new.target === undefined) throw TypeError("Constructor requires new"); + } +} + + +//// [newTargetUndefinedEquality.js] +"use strict"; +class ConstructorGuard { + constructor() { + if (new.target === undefined) + throw TypeError("Constructor requires new"); + } +} diff --git a/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.symbols b/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.symbols new file mode 100644 index 0000000000000..4728644830fb5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/newTargetUndefinedEquality.ts] //// + +=== newTargetUndefinedEquality.ts === +class ConstructorGuard { +>ConstructorGuard : Symbol(ConstructorGuard, Decl(newTargetUndefinedEquality.ts, 0, 0)) + + constructor() { + if (new.target === undefined) throw TypeError("Constructor requires new"); +>new.target : Symbol(ConstructorGuard, Decl(newTargetUndefinedEquality.ts, 0, 0)) +>target : Symbol(ConstructorGuard, Decl(newTargetUndefinedEquality.ts, 0, 0)) +>undefined : Symbol(undefined) +>TypeError : Symbol(TypeError, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.types b/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.types new file mode 100644 index 0000000000000..55a7ec4a957e0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/newTargetUndefinedEquality.types @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/newTargetUndefinedEquality.ts] //// + +=== newTargetUndefinedEquality.ts === +class ConstructorGuard { +>ConstructorGuard : ConstructorGuard + + constructor() { + if (new.target === undefined) throw TypeError("Constructor requires new"); +>new.target === undefined : boolean +>new.target : typeof ConstructorGuard +>target : typeof ConstructorGuard +>undefined : undefined +>TypeError("Constructor requires new") : TypeError +>TypeError : TypeErrorConstructor +>"Constructor requires new" : "Constructor requires new" + } +} + diff --git a/tsc/testdata/tests/cases/compiler/newTargetUndefinedEquality.ts b/tsc/testdata/tests/cases/compiler/newTargetUndefinedEquality.ts new file mode 100644 index 0000000000000..9cda8dc74831d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/newTargetUndefinedEquality.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es2015 + +class ConstructorGuard { + constructor() { + if (new.target === undefined) throw TypeError("Constructor requires new"); + } +} From b513608e88b7ec9e453169d7bdc2bc71bd8bd0a2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 19:27:22 -0700 Subject: [PATCH 071/116] Add historical coverage: logical not undefined comparison Exact closed/unmerged incomplete PR60433 equality experiment, placeholder TS2870 (not nullish-coalescing syntax). Complete original FormatJS seven-file Segmenter BUILD source/generated CLDR/own workspace route and selected original tslib2.8.1, versus complete NodeGuards/helper projection with selected original ESTree0.0.51 SRI, not full monorepo/Bazel or four Obfuscator projects/bot installs. Original FormatJS native5102baseUrl+5108ES5 and projected NodeGuards native5108node10 retained; separate supported source profiles pass. Minimal integrated cases preserve current accepted equality syntax, not an assertion that the source logical-not predicate is correct. Genuine source negation comparison is an intentional candidate tightening; class new.target guard is reachable under original ES5 downlevel only for a null-prototype receiver, not an ordinary {} receiver. Current supported ES2015 tests do not claim native ES5 support. Existing null/undefined comparison fallout does not exercise these two operand forms; existing new.target nullish-coalescing is unchanged across historical snapshots. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60433#issuecomment-2460603054 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/logicalNotUndefinedComparison.js | 13 +++++++++++++ .../logicalNotUndefinedComparison.symbols | 15 +++++++++++++++ .../logicalNotUndefinedComparison.types | 17 +++++++++++++++++ .../compiler/logicalNotUndefinedComparison.ts | 6 ++++++ 4 files changed, 51 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.js create mode 100644 tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.types create mode 100644 tsc/testdata/tests/cases/compiler/logicalNotUndefinedComparison.ts diff --git a/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.js b/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.js new file mode 100644 index 0000000000000..2fbdf28f79310 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/logicalNotUndefinedComparison.ts] //// + +//// [logicalNotUndefinedComparison.ts] +function isNode(object: { type?: string }) { + return !object.type !== undefined; +} + + +//// [logicalNotUndefinedComparison.js] +"use strict"; +function isNode(object) { + return !object.type !== undefined; +} diff --git a/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.symbols b/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.symbols new file mode 100644 index 0000000000000..2864dd480aff8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/logicalNotUndefinedComparison.ts] //// + +=== logicalNotUndefinedComparison.ts === +function isNode(object: { type?: string }) { +>isNode : Symbol(isNode, Decl(logicalNotUndefinedComparison.ts, 0, 0)) +>object : Symbol(object, Decl(logicalNotUndefinedComparison.ts, 0, 16)) +>type : Symbol(type, Decl(logicalNotUndefinedComparison.ts, 0, 25)) + + return !object.type !== undefined; +>object.type : Symbol(type, Decl(logicalNotUndefinedComparison.ts, 0, 25)) +>object : Symbol(object, Decl(logicalNotUndefinedComparison.ts, 0, 16)) +>type : Symbol(type, Decl(logicalNotUndefinedComparison.ts, 0, 25)) +>undefined : Symbol(undefined) +} + diff --git a/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.types b/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.types new file mode 100644 index 0000000000000..935f17724cc2d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/logicalNotUndefinedComparison.types @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/logicalNotUndefinedComparison.ts] //// + +=== logicalNotUndefinedComparison.ts === +function isNode(object: { type?: string }) { +>isNode : (object: { type?: string; }) => boolean +>object : { type?: string; } +>type : string | undefined + + return !object.type !== undefined; +>!object.type !== undefined : boolean +>!object.type : boolean +>object.type : string | undefined +>object : { type?: string; } +>type : string | undefined +>undefined : undefined +} + diff --git a/tsc/testdata/tests/cases/compiler/logicalNotUndefinedComparison.ts b/tsc/testdata/tests/cases/compiler/logicalNotUndefinedComparison.ts new file mode 100644 index 0000000000000..f63b3e95c5a91 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/logicalNotUndefinedComparison.ts @@ -0,0 +1,6 @@ +// @strict: true +// @target: es2015 + +function isNode(object: { type?: string }) { + return !object.type !== undefined; +} From ec8722f0f3465f0370f6b3f6483eebcf762380dd Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 19:56:33 -0700 Subject: [PATCH 072/116] Add historical coverage: generic contextual overload composition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closed/unmerged nonFixingMapper experiment: both complete original configured TodoMVC/Counter programs0→their sole2322, with genuine frozen1068-package selected SDK, original1912 descriptors/56 optional skips, and seven source-owned declaration SDKs regenerated by original frozen TypeScript5.5.4, not published substitutes or recovered bot outputs. Replacing only actual compose initialization by equivalent contextual next-arrow gives both programs0/0. SDK-free six-nonblank-line test has old fallback return Next/head selected-overload return {extra:unknown}, losing the generic input in the return; current native0 and retained-input/not-any/not-never controls0. Overload and contextual target are essential. Removing the final fallback is invalid before/current2345 and rejected, as are the extractor's2345→2322 reductions/three-function simplified kernel. All21 closest existing contextual/compose tests retain diagnostics, inferred variables/initializers and callback parameters; one already-negative conformance case changes only diagnostic wording, not this valid-code regression. Original native TodoMVC2882 CSS-policy difference is preserved; separate noUncheckedSideEffectImports:false0; original Counter0. Pure workspace-source alias expansion changes ambient/config discovery and is separately not clean. No whole bot/runtime-build or compiler-fix claim. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60557#issuecomment-2494343862 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/genericContextualComposition.js | 13 +++++ .../genericContextualComposition.symbols | 51 +++++++++++++++++++ .../genericContextualComposition.types | 32 ++++++++++++ .../compiler/genericContextualComposition.ts | 7 +++ 4 files changed, 103 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/genericContextualComposition.js create mode 100644 tsc/testdata/baselines/reference/compiler/genericContextualComposition.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/genericContextualComposition.types create mode 100644 tsc/testdata/tests/cases/compiler/genericContextualComposition.ts diff --git a/tsc/testdata/baselines/reference/compiler/genericContextualComposition.js b/tsc/testdata/baselines/reference/compiler/genericContextualComposition.js new file mode 100644 index 0000000000000..e94f45b3a0fe2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericContextualComposition.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/genericContextualComposition.ts] //// + +//// [genericContextualComposition.ts] +type Enhancer = (next: Next) => Next & Extension; +declare function compose(first: (value: A) => Result, second: (...args: Args) => A): (...args: Args) => Result; +declare function compose(...functions: Function[]): (...args: any[]) => Result; +declare const instrument: Enhancer<{ extra: unknown }>, persist: Enhancer; +const enhancer: Enhancer = compose(instrument, persist); + + +//// [genericContextualComposition.js] +"use strict"; +const enhancer = compose(instrument, persist); diff --git a/tsc/testdata/baselines/reference/compiler/genericContextualComposition.symbols b/tsc/testdata/baselines/reference/compiler/genericContextualComposition.symbols new file mode 100644 index 0000000000000..630b5db1840b7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericContextualComposition.symbols @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/genericContextualComposition.ts] //// + +=== genericContextualComposition.ts === +type Enhancer = (next: Next) => Next & Extension; +>Enhancer : Symbol(Enhancer, Decl(genericContextualComposition.ts, 0, 0)) +>Extension : Symbol(Extension, Decl(genericContextualComposition.ts, 0, 14)) +>Next : Symbol(Next, Decl(genericContextualComposition.ts, 0, 44)) +>next : Symbol(next, Decl(genericContextualComposition.ts, 0, 61)) +>Next : Symbol(Next, Decl(genericContextualComposition.ts, 0, 44)) +>Next : Symbol(Next, Decl(genericContextualComposition.ts, 0, 44)) +>Extension : Symbol(Extension, Decl(genericContextualComposition.ts, 0, 14)) + +declare function compose(first: (value: A) => Result, second: (...args: Args) => A): (...args: Args) => Result; +>compose : Symbol(compose, Decl(genericContextualComposition.ts, 0, 93), Decl(genericContextualComposition.ts, 1, 142)) +>A : Symbol(A, Decl(genericContextualComposition.ts, 1, 25)) +>Args : Symbol(Args, Decl(genericContextualComposition.ts, 1, 27)) +>Result : Symbol(Result, Decl(genericContextualComposition.ts, 1, 47)) +>first : Symbol(first, Decl(genericContextualComposition.ts, 1, 56)) +>value : Symbol(value, Decl(genericContextualComposition.ts, 1, 64)) +>A : Symbol(A, Decl(genericContextualComposition.ts, 1, 25)) +>Result : Symbol(Result, Decl(genericContextualComposition.ts, 1, 47)) +>second : Symbol(second, Decl(genericContextualComposition.ts, 1, 84)) +>args : Symbol(args, Decl(genericContextualComposition.ts, 1, 94)) +>Args : Symbol(Args, Decl(genericContextualComposition.ts, 1, 27)) +>A : Symbol(A, Decl(genericContextualComposition.ts, 1, 25)) +>args : Symbol(args, Decl(genericContextualComposition.ts, 1, 117)) +>Args : Symbol(Args, Decl(genericContextualComposition.ts, 1, 27)) +>Result : Symbol(Result, Decl(genericContextualComposition.ts, 1, 47)) + +declare function compose(...functions: Function[]): (...args: any[]) => Result; +>compose : Symbol(compose, Decl(genericContextualComposition.ts, 0, 93), Decl(genericContextualComposition.ts, 1, 142)) +>Result : Symbol(Result, Decl(genericContextualComposition.ts, 2, 25)) +>functions : Symbol(functions, Decl(genericContextualComposition.ts, 2, 33)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>args : Symbol(args, Decl(genericContextualComposition.ts, 2, 61)) +>Result : Symbol(Result, Decl(genericContextualComposition.ts, 2, 25)) + +declare const instrument: Enhancer<{ extra: unknown }>, persist: Enhancer; +>instrument : Symbol(instrument, Decl(genericContextualComposition.ts, 3, 13)) +>Enhancer : Symbol(Enhancer, Decl(genericContextualComposition.ts, 0, 0)) +>extra : Symbol(extra, Decl(genericContextualComposition.ts, 3, 36)) +>persist : Symbol(persist, Decl(genericContextualComposition.ts, 3, 55)) +>Enhancer : Symbol(Enhancer, Decl(genericContextualComposition.ts, 0, 0)) + +const enhancer: Enhancer = compose(instrument, persist); +>enhancer : Symbol(enhancer, Decl(genericContextualComposition.ts, 4, 5)) +>Enhancer : Symbol(Enhancer, Decl(genericContextualComposition.ts, 0, 0)) +>compose : Symbol(compose, Decl(genericContextualComposition.ts, 0, 93), Decl(genericContextualComposition.ts, 1, 142)) +>instrument : Symbol(instrument, Decl(genericContextualComposition.ts, 3, 13)) +>persist : Symbol(persist, Decl(genericContextualComposition.ts, 3, 55)) + diff --git a/tsc/testdata/baselines/reference/compiler/genericContextualComposition.types b/tsc/testdata/baselines/reference/compiler/genericContextualComposition.types new file mode 100644 index 0000000000000..c240cc68f21f9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericContextualComposition.types @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/genericContextualComposition.ts] //// + +=== genericContextualComposition.ts === +type Enhancer = (next: Next) => Next & Extension; +>Enhancer : Enhancer +>next : Next + +declare function compose(first: (value: A) => Result, second: (...args: Args) => A): (...args: Args) => Result; +>compose : { (first: (value: A) => Result, second: (...args: Args) => A): (...args: Args) => Result; (...functions: Function[]): (...args: any[]) => Result_1; } +>first : (value: A) => Result +>value : A +>second : (...args: Args) => A +>args : Args +>args : Args + +declare function compose(...functions: Function[]): (...args: any[]) => Result; +>compose : { (first: (value: A) => Result_1, second: (...args: Args) => A): (...args: Args) => Result_1; (...functions: Function[]): (...args: any[]) => Result; } +>functions : Function[] +>args : any[] + +declare const instrument: Enhancer<{ extra: unknown }>, persist: Enhancer; +>instrument : Enhancer<{ extra: unknown; }> +>extra : unknown +>persist : Enhancer<{}> + +const enhancer: Enhancer = compose(instrument, persist); +>enhancer : Enhancer<{}> +>compose(instrument, persist) : (...args: any[]) => Next +>compose : { (first: (value: A) => Result, second: (...args: Args) => A): (...args: Args) => Result; (...functions: Function[]): (...args: any[]) => Result; } +>instrument : Enhancer<{ extra: unknown; }> +>persist : Enhancer<{}> + diff --git a/tsc/testdata/tests/cases/compiler/genericContextualComposition.ts b/tsc/testdata/tests/cases/compiler/genericContextualComposition.ts new file mode 100644 index 0000000000000..dd879a4665c84 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/genericContextualComposition.ts @@ -0,0 +1,7 @@ +// @strict: true + +type Enhancer = (next: Next) => Next & Extension; +declare function compose(first: (value: A) => Result, second: (...args: Args) => A): (...args: Args) => Result; +declare function compose(...functions: Function[]): (...args: any[]) => Result; +declare const instrument: Enhancer<{ extra: unknown }>, persist: Enhancer; +const enhancer: Enhancer = compose(instrument, persist); From bf8819813994de28f74ddd7946f39542f5d219d3 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 20:25:52 -0700 Subject: [PATCH 073/116] Add historical coverage: dom iterable generic dataset keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exact original parent6f6efb41/finalheadf88cc72f original libs: two complete frozen Bootstrap projects0→2536 at32:19 and34:14; eight-line SDK-free generic dataset read/delete0→two2536; native same two2536, NOT a fixed/current-clean claim. Explicit DOM.Iterable causes same before errors; restricting only keys to string|number restores both full projects0/0/native0. Fourteen closest existing fixtures unchanged. Closed/unmerged experiment; separate cleanup62037 is not merge/coverage evidence. Origin: https://github.com/microsoft/TypeScript/pull/62025#issuecomment-3051816920 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../domIterableGenericDatasetKeys.errors.txt | 14 ++++++++++ .../compiler/domIterableGenericDatasetKeys.js | 15 +++++++++++ .../domIterableGenericDatasetKeys.symbols | 26 +++++++++++++++++++ .../domIterableGenericDatasetKeys.types | 25 ++++++++++++++++++ .../compiler/domIterableGenericDatasetKeys.ts | 8 ++++++ 5 files changed, 88 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.js create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.types create mode 100644 tsc/testdata/tests/cases/compiler/domIterableGenericDatasetKeys.ts diff --git a/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.errors.txt b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.errors.txt new file mode 100644 index 0000000000000..352602cfb9faa --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.errors.txt @@ -0,0 +1,14 @@ +domIterableGenericDatasetKeys.ts(2,19): error TS2536: Type 'Key' cannot be used to index type 'DOMStringMap'. +domIterableGenericDatasetKeys.ts(3,12): error TS2536: Type 'Key' cannot be used to index type 'DOMStringMap'. + + +==== domIterableGenericDatasetKeys.ts (2 errors) ==== + function restore(key: Key, element: HTMLElement) { + const value = element.dataset[key]; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2536: Type 'Key' cannot be used to index type 'DOMStringMap'. + delete element.dataset[key]; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2536: Type 'Key' cannot be used to index type 'DOMStringMap'. + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.js b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.js new file mode 100644 index 0000000000000..bf2c038e20928 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/domIterableGenericDatasetKeys.ts] //// + +//// [domIterableGenericDatasetKeys.ts] +function restore(key: Key, element: HTMLElement) { + const value = element.dataset[key]; + delete element.dataset[key]; +} + + +//// [domIterableGenericDatasetKeys.js] +"use strict"; +function restore(key, element) { + const value = element.dataset[key]; + delete element.dataset[key]; +} diff --git a/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.symbols b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.symbols new file mode 100644 index 0000000000000..609042b3e9ec8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.symbols @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/domIterableGenericDatasetKeys.ts] //// + +=== domIterableGenericDatasetKeys.ts === +function restore(key: Key, element: HTMLElement) { +>restore : Symbol(restore, Decl(domIterableGenericDatasetKeys.ts, 0, 0)) +>Key : Symbol(Key, Decl(domIterableGenericDatasetKeys.ts, 0, 17)) +>CSSStyleDeclaration : Symbol(CSSStyleDeclaration, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>key : Symbol(key, Decl(domIterableGenericDatasetKeys.ts, 0, 56)) +>Key : Symbol(Key, Decl(domIterableGenericDatasetKeys.ts, 0, 17)) +>element : Symbol(element, Decl(domIterableGenericDatasetKeys.ts, 0, 65)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + const value = element.dataset[key]; +>value : Symbol(value, Decl(domIterableGenericDatasetKeys.ts, 1, 9)) +>element.dataset : Symbol(HTMLOrSVGOrMathMLElement.dataset, Decl(lib.dom.d.ts, --, --)) +>element : Symbol(element, Decl(domIterableGenericDatasetKeys.ts, 0, 65)) +>dataset : Symbol(HTMLOrSVGOrMathMLElement.dataset, Decl(lib.dom.d.ts, --, --)) +>key : Symbol(key, Decl(domIterableGenericDatasetKeys.ts, 0, 56)) + + delete element.dataset[key]; +>element.dataset : Symbol(HTMLOrSVGOrMathMLElement.dataset, Decl(lib.dom.d.ts, --, --)) +>element : Symbol(element, Decl(domIterableGenericDatasetKeys.ts, 0, 65)) +>dataset : Symbol(HTMLOrSVGOrMathMLElement.dataset, Decl(lib.dom.d.ts, --, --)) +>key : Symbol(key, Decl(domIterableGenericDatasetKeys.ts, 0, 56)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.types b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.types new file mode 100644 index 0000000000000..d2922190b7151 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableGenericDatasetKeys.types @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/domIterableGenericDatasetKeys.ts] //// + +=== domIterableGenericDatasetKeys.ts === +function restore(key: Key, element: HTMLElement) { +>restore : (key: Key, element: HTMLElement) => void +>key : Key +>element : HTMLElement + + const value = element.dataset[key]; +>value : any +>element.dataset[key] : any +>element.dataset : DOMStringMap +>element : HTMLElement +>dataset : DOMStringMap +>key : Key + + delete element.dataset[key]; +>delete element.dataset[key] : boolean +>element.dataset[key] : any +>element.dataset : DOMStringMap +>element : HTMLElement +>dataset : DOMStringMap +>key : Key +} + diff --git a/tsc/testdata/tests/cases/compiler/domIterableGenericDatasetKeys.ts b/tsc/testdata/tests/cases/compiler/domIterableGenericDatasetKeys.ts new file mode 100644 index 0000000000000..ee360d17f35fb --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domIterableGenericDatasetKeys.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es2015 +// @lib: esnext, dom + +function restore(key: Key, element: HTMLElement) { + const value = element.dataset[key]; + delete element.dataset[key]; +} From 9239db37fb0fe411191697214d4f37e8aef5caaa Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 20:25:56 -0700 Subject: [PATCH 074/116] Add historical coverage: dom iterable symbol mapped value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exact parent6f6efb41/finalheadf88cc72f complete original293-root Mitosis build/genuine source-selected SDK2.1.1:0→sole2345 at784:5, source optional iterator function versus target optional string. Separate IDE retains original unrelated2305. Seven-line SDK-free symbol-key Pick/mapped string target0→2345/native SAME2345. Original native baseUrl5102; removal-only2345, separate symbol-removal plus option removal0. Full original Yarn4.1.1 SDK verified, with twelve runtime Windows archives missing ORIGINAL checksums explicitly not falsely SRI-verified; all348 loaded SDK sources byte-verified. Fourteen closest tests unchanged; no compiler fix. Origin: https://github.com/microsoft/TypeScript/pull/62025#issuecomment-3051816920 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../domIterableSymbolMappedValue.errors.txt | 16 ++++++++++++++ .../compiler/domIterableSymbolMappedValue.js | 11 ++++++++++ .../domIterableSymbolMappedValue.symbols | 21 +++++++++++++++++++ .../domIterableSymbolMappedValue.types | 15 +++++++++++++ .../compiler/domIterableSymbolMappedValue.ts | 7 +++++++ 5 files changed, 70 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.js create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.types create mode 100644 tsc/testdata/tests/cases/compiler/domIterableSymbolMappedValue.ts diff --git a/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.errors.txt b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.errors.txt new file mode 100644 index 0000000000000..8a01bf160bb5b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.errors.txt @@ -0,0 +1,16 @@ +domIterableSymbolMappedValue.ts(3,9): error TS2345: Argument of type 'Partial>' is not assignable to parameter of type 'Partial>'. + Types of property '[iterator]' are incompatible. + Type '(() => ArrayIterator) | undefined' is not assignable to type 'string | undefined'. + Type '() => ArrayIterator' is not assignable to type 'string'. + + +==== domIterableSymbolMappedValue.ts (1 errors) ==== + declare const styles: Partial>; + declare function element(styles: Partial>): void; + element(styles); + ~~~~~~ +!!! error TS2345: Argument of type 'Partial>' is not assignable to parameter of type 'Partial>'. +!!! error TS2345: Types of property '[iterator]' are incompatible. +!!! error TS2345: Type '(() => ArrayIterator) | undefined' is not assignable to type 'string | undefined'. +!!! error TS2345: Type '() => ArrayIterator' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.js b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.js new file mode 100644 index 0000000000000..98a3475277f56 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.js @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/domIterableSymbolMappedValue.ts] //// + +//// [domIterableSymbolMappedValue.ts] +declare const styles: Partial>; +declare function element(styles: Partial>): void; +element(styles); + + +//// [domIterableSymbolMappedValue.js] +"use strict"; +element(styles); diff --git a/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.symbols b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.symbols new file mode 100644 index 0000000000000..bda0738bcfe2e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/domIterableSymbolMappedValue.ts] //// + +=== domIterableSymbolMappedValue.ts === +declare const styles: Partial>; +>styles : Symbol(styles, Decl(domIterableSymbolMappedValue.ts, 0, 13)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>CSSStyleDeclaration : Symbol(CSSStyleDeclaration, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>CSSStyleDeclaration : Symbol(CSSStyleDeclaration, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +declare function element(styles: Partial>): void; +>element : Symbol(element, Decl(domIterableSymbolMappedValue.ts, 0, 93)) +>styles : Symbol(styles, Decl(domIterableSymbolMappedValue.ts, 1, 25)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>CSSStyleDeclaration : Symbol(CSSStyleDeclaration, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +element(styles); +>element : Symbol(element, Decl(domIterableSymbolMappedValue.ts, 0, 93)) +>styles : Symbol(styles, Decl(domIterableSymbolMappedValue.ts, 0, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.types b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.types new file mode 100644 index 0000000000000..9dc7d5c608c27 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domIterableSymbolMappedValue.types @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/domIterableSymbolMappedValue.ts] //// + +=== domIterableSymbolMappedValue.ts === +declare const styles: Partial>; +>styles : Partial> + +declare function element(styles: Partial>): void; +>element : (styles: Partial>) => void +>styles : Partial> + +element(styles); +>element(styles) : void +>element : (styles: Partial>) => void +>styles : Partial> + diff --git a/tsc/testdata/tests/cases/compiler/domIterableSymbolMappedValue.ts b/tsc/testdata/tests/cases/compiler/domIterableSymbolMappedValue.ts new file mode 100644 index 0000000000000..a4c9a4628804f --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domIterableSymbolMappedValue.ts @@ -0,0 +1,7 @@ +// @strict: true +// @target: es2015 +// @lib: esnext, dom + +declare const styles: Partial>; +declare function element(styles: Partial>): void; +element(styles); From 209d6d6854e519ac994140dee172e0d5e2f05d7e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 21:15:51 -0700 Subject: [PATCH 075/116] Add historical coverage: object entries generic mapped values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closed/unmerged library-only PR61074; shared historical5.8 checker with exact parent0652664e/head d3471e26 libraries, not a recovered bot installation. Exact reported tsec3718/4075 program0→19 and monaco382/1193 program0→3; changing only entries back to prior overload makes each whole after program0, with after fromEntries unchanged. All1578 physical SDK records and1326 original-SRI tarballs verified; all296 main-loaded SDK files byte-compared to original archives and both reported closures proven subsets. Original native tsec346 diagnostics, none owned; original monaco5095+5108x2 prevent source checking. Separate main4411/4768 is a cross-check only, native554/zero owned, not the reported configurations or a clean native project. Two n values genuinely any→mapped indexed value|undefined while keys staystring; recursive observables, DOM declarations, conditional wrappers, loops and branch tests are unnecessary. Required still regresses, so mapped generic context—not optionality alone—is essential. Existing array-value and object-key-never assertions cover16 rows; historical checker crash on later computed-property regression explicitly excluded, not counted as unchanged. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61074#issuecomment-2675987252 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../objectEntriesGenericMappedValues.js | 17 +++++++++++ .../objectEntriesGenericMappedValues.symbols | 29 ++++++++++++++++++ .../objectEntriesGenericMappedValues.types | 30 +++++++++++++++++++ .../objectEntriesGenericMappedValues.ts | 8 +++++ 4 files changed, 84 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.js create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.types create mode 100644 tsc/testdata/tests/cases/compiler/objectEntriesGenericMappedValues.ts diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.js b/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.js new file mode 100644 index 0000000000000..f3b064663df03 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/objectEntriesGenericMappedValues.ts] //// + +//// [objectEntriesGenericMappedValues.ts] +function read(attributes: Partial) { + const [, value] = Object.entries(attributes)[0]; + Object.entries(value); + const tabIndex: number = value; +} + + +//// [objectEntriesGenericMappedValues.js] +"use strict"; +function read(attributes) { + const [, value] = Object.entries(attributes)[0]; + Object.entries(value); + const tabIndex = value; +} diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.symbols b/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.symbols new file mode 100644 index 0000000000000..2e99e1e18173a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/objectEntriesGenericMappedValues.ts] //// + +=== objectEntriesGenericMappedValues.ts === +function read(attributes: Partial) { +>read : Symbol(read, Decl(objectEntriesGenericMappedValues.ts, 0, 0)) +>T : Symbol(T, Decl(objectEntriesGenericMappedValues.ts, 0, 14)) +>tabIndex : Symbol(tabIndex, Decl(objectEntriesGenericMappedValues.ts, 0, 25)) +>attributes : Symbol(attributes, Decl(objectEntriesGenericMappedValues.ts, 0, 46)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(objectEntriesGenericMappedValues.ts, 0, 14)) + + const [, value] = Object.entries(attributes)[0]; +>value : Symbol(value, Decl(objectEntriesGenericMappedValues.ts, 1, 12)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>attributes : Symbol(attributes, Decl(objectEntriesGenericMappedValues.ts, 0, 46)) + + Object.entries(value); +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>value : Symbol(value, Decl(objectEntriesGenericMappedValues.ts, 1, 12)) + + const tabIndex: number = value; +>tabIndex : Symbol(tabIndex, Decl(objectEntriesGenericMappedValues.ts, 3, 9)) +>value : Symbol(value, Decl(objectEntriesGenericMappedValues.ts, 1, 12)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.types b/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.types new file mode 100644 index 0000000000000..12fcc648abd4b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/objectEntriesGenericMappedValues.types @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/objectEntriesGenericMappedValues.ts] //// + +=== objectEntriesGenericMappedValues.ts === +function read(attributes: Partial) { +>read : (attributes: Partial) => void +>tabIndex : number +>attributes : Partial + + const [, value] = Object.entries(attributes)[0]; +>value : any +>Object.entries(attributes)[0] : [string, any] +>Object.entries(attributes) : [string, any][] +>Object.entries : { (o: { [s: string]: T_1; } | ArrayLike): [string, T_1][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T_1; } | ArrayLike): [string, T_1][]; (o: {}): [string, any][]; } +>attributes : Partial +>0 : 0 + + Object.entries(value); +>Object.entries(value) : [string, unknown][] +>Object.entries : { (o: { [s: string]: T_1; } | ArrayLike): [string, T_1][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T_1; } | ArrayLike): [string, T_1][]; (o: {}): [string, any][]; } +>value : any + + const tabIndex: number = value; +>tabIndex : number +>value : any +} + diff --git a/tsc/testdata/tests/cases/compiler/objectEntriesGenericMappedValues.ts b/tsc/testdata/tests/cases/compiler/objectEntriesGenericMappedValues.ts new file mode 100644 index 0000000000000..c22b814feabbe --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/objectEntriesGenericMappedValues.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es2017 + +function read(attributes: Partial) { + const [, value] = Object.entries(attributes)[0]; + Object.entries(value); + const tabIndex: number = value; +} From 43d9c7393f3d37a9fd5ad18a645058d5790b1c9a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Oct 2026 21:59:39 -0700 Subject: [PATCH 076/116] Add historical coverage: large discriminant union array predicate Closed/unmerged origin-preservation experiment: exact parent83dc0bb2 and initial5d3fe0a1 are clean, actual Apr17 pre-comment5c8de5d6 and genuine same-trigger npm5.9.0-pr-61589-2/runtime5.9.0-insiders.20250417 reproduce both whole unchanged Apollo configs251/1085 and398/1442 with exact2339 at182:20/186:20; final Apr21 head29ae00ac is clean and is NOT substituted for the failing snapshot. Original compiler tgz SHA512+SHA1 recomputed, but exact top400 compiler/comparison-main SHA unavailable. All1110 original SDK descriptors,1064 physical manifests and1068 loaded hashes checked; SDK tarball bytes not redownloaded/recomputed; one unloaded original Git descriptor lacks SRI. Actual genuine GraphQL43-kind union and custom readonly-array predicate cause false-branch receivers to retain arrays; post-error any is error-any, not source-any. Parent's ten-member readonly-unknown predicate kernel and60 matrices independently rerun. Further controlled reduction changes BOTH input array to mutable and guard to genuine standard Array.isArray, eliminating the custom predicate declaration while preserving exact precomment/pack2339 and before/initial/final/native0. Nine kinds is clean in all phases: ten unique kinds are the discriminant-map optimization threshold. Twenty-one original single-file profiles plus proper two-file trackedSymbolsNoCrash VFS are unchanged in source diagnostics and actual observed receiver/value types; packed coAndContra library-only diagnostic line drift is not a source regression. Expanded historical cross-product OOM retained/excluded, never called covered. Original whole-native options unsupported; separately supported options retain24 root/4 editor unrelated errors, none owned, never full native0. Whole-source add-only kind guard and compiler later-discriminator-only fix each remove both failures; no suite implementation change. Origin: https://redirect.github.com/microsoft/TypeScript/pull/61589#issuecomment-2813357259 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../largeDiscriminantUnionArrayPredicate.js | 27 ++++++++++ ...rgeDiscriminantUnionArrayPredicate.symbols | 53 +++++++++++++++++++ ...largeDiscriminantUnionArrayPredicate.types | 53 +++++++++++++++++++ .../largeDiscriminantUnionArrayPredicate.ts | 19 +++++++ 4 files changed, 152 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.js create mode 100644 tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.types create mode 100644 tsc/testdata/tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts diff --git a/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.js b/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.js new file mode 100644 index 0000000000000..3f1be9bd9aeef --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts] //// + +//// [largeDiscriminantUnionArrayPredicate.ts] +type TreeNode = + | { kind: 0 } + | { kind: 1 } + | { kind: 2 } + | { kind: 3 } + | { kind: 4 } + | { kind: 5 } + | { kind: 6 } + | { kind: 7 } + | { kind: 8 } + | { kind: 9 }; + +declare const ancestor: TreeNode | TreeNode[]; + +if (!Array.isArray(ancestor)) { + ancestor.kind; +} + + +//// [largeDiscriminantUnionArrayPredicate.js] +"use strict"; +if (!Array.isArray(ancestor)) { + ancestor.kind; +} diff --git a/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.symbols b/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.symbols new file mode 100644 index 0000000000000..06fea956193f7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.symbols @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts] //// + +=== largeDiscriminantUnionArrayPredicate.ts === +type TreeNode = +>TreeNode : Symbol(TreeNode, Decl(largeDiscriminantUnionArrayPredicate.ts, 0, 0)) + + | { kind: 0 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 1, 7)) + + | { kind: 1 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 2, 7)) + + | { kind: 2 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 3, 7)) + + | { kind: 3 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 4, 7)) + + | { kind: 4 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 5, 7)) + + | { kind: 5 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 6, 7)) + + | { kind: 6 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 7, 7)) + + | { kind: 7 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 8, 7)) + + | { kind: 8 } +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 9, 7)) + + | { kind: 9 }; +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 10, 7)) + +declare const ancestor: TreeNode | TreeNode[]; +>ancestor : Symbol(ancestor, Decl(largeDiscriminantUnionArrayPredicate.ts, 12, 13)) +>TreeNode : Symbol(TreeNode, Decl(largeDiscriminantUnionArrayPredicate.ts, 0, 0)) +>TreeNode : Symbol(TreeNode, Decl(largeDiscriminantUnionArrayPredicate.ts, 0, 0)) + +if (!Array.isArray(ancestor)) { +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 4 more) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>ancestor : Symbol(ancestor, Decl(largeDiscriminantUnionArrayPredicate.ts, 12, 13)) + + ancestor.kind; +>ancestor.kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 1, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 2, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 3, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 4, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 5, 7) ... and 5 more) +>ancestor : Symbol(ancestor, Decl(largeDiscriminantUnionArrayPredicate.ts, 12, 13)) +>kind : Symbol(kind, Decl(largeDiscriminantUnionArrayPredicate.ts, 1, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 2, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 3, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 4, 7), Decl(largeDiscriminantUnionArrayPredicate.ts, 5, 7) ... and 5 more) +} + diff --git a/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.types b/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.types new file mode 100644 index 0000000000000..1f5ff2c13a149 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/largeDiscriminantUnionArrayPredicate.types @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts] //// + +=== largeDiscriminantUnionArrayPredicate.ts === +type TreeNode = +>TreeNode : TreeNode + + | { kind: 0 } +>kind : 0 + + | { kind: 1 } +>kind : 1 + + | { kind: 2 } +>kind : 2 + + | { kind: 3 } +>kind : 3 + + | { kind: 4 } +>kind : 4 + + | { kind: 5 } +>kind : 5 + + | { kind: 6 } +>kind : 6 + + | { kind: 7 } +>kind : 7 + + | { kind: 8 } +>kind : 8 + + | { kind: 9 }; +>kind : 9 + +declare const ancestor: TreeNode | TreeNode[]; +>ancestor : TreeNode[] | TreeNode + +if (!Array.isArray(ancestor)) { +>!Array.isArray(ancestor) : boolean +>Array.isArray(ancestor) : boolean +>Array.isArray : (arg: any) => arg is any[] +>Array : ArrayConstructor +>isArray : (arg: any) => arg is any[] +>ancestor : TreeNode[] | TreeNode + + ancestor.kind; +>ancestor.kind : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +>ancestor : TreeNode +>kind : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +} + diff --git a/tsc/testdata/tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts b/tsc/testdata/tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts new file mode 100644 index 0000000000000..cbc0d6eaece2b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/largeDiscriminantUnionArrayPredicate.ts @@ -0,0 +1,19 @@ +// @strict: true + +type TreeNode = + | { kind: 0 } + | { kind: 1 } + | { kind: 2 } + | { kind: 3 } + | { kind: 4 } + | { kind: 5 } + | { kind: 6 } + | { kind: 7 } + | { kind: 8 } + | { kind: 9 }; + +declare const ancestor: TreeNode | TreeNode[]; + +if (!Array.isArray(ancestor)) { + ancestor.kind; +} From 0052a48d3ff6e07fb07316a14effca7a88e324f3 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 00:09:38 -0700 Subject: [PATCH 077/116] Add historical coverage: async callback state union inference Reproduce the Commerce action-state regression where awaited-like inference priority discards async callback return candidates in favor of a null initial state, losing the payload overload and rejecting the subsequent bind. Self-contained standard-library-only reduction; six original source diagnostics share this mechanism. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60334#issuecomment-2434099048 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../promiseUnionCallbackStateInference.js | 21 +++++++ ...promiseUnionCallbackStateInference.symbols | 57 +++++++++++++++++++ .../promiseUnionCallbackStateInference.types | 47 +++++++++++++++ .../promiseUnionCallbackStateInference.ts | 15 +++++ 4 files changed, 140 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.js create mode 100644 tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.types create mode 100644 tsc/testdata/tests/cases/compiler/promiseUnionCallbackStateInference.ts diff --git a/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.js b/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.js new file mode 100644 index 0000000000000..2264c71981f61 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/promiseUnionCallbackStateInference.ts] //// + +//// [promiseUnionCallbackStateInference.ts] +declare function createAction( + action: (state: State) => State | Promise, + initialState: State, +): () => void; +declare function createAction( + action: (state: State, payload: string) => State | Promise, + initialState: State, +): (payload: string) => void; + +declare const action: (previous: unknown, value: string) => Promise; +const dispatch = createAction(action, null); +const bound = dispatch.bind(null, "value"); + + +//// [promiseUnionCallbackStateInference.js] +"use strict"; +const dispatch = createAction(action, null); +const bound = dispatch.bind(null, "value"); diff --git a/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.symbols b/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.symbols new file mode 100644 index 0000000000000..acb7064e5172a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.symbols @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/promiseUnionCallbackStateInference.ts] //// + +=== promiseUnionCallbackStateInference.ts === +declare function createAction( +>createAction : Symbol(createAction, Decl(promiseUnionCallbackStateInference.ts, 0, 0), Decl(promiseUnionCallbackStateInference.ts, 3, 14)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 0, 30)) + + action: (state: State) => State | Promise, +>action : Symbol(action, Decl(promiseUnionCallbackStateInference.ts, 0, 37)) +>state : Symbol(state, Decl(promiseUnionCallbackStateInference.ts, 1, 13)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 0, 30)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 0, 30)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 0, 30)) + + initialState: State, +>initialState : Symbol(initialState, Decl(promiseUnionCallbackStateInference.ts, 1, 53)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 0, 30)) + +): () => void; +declare function createAction( +>createAction : Symbol(createAction, Decl(promiseUnionCallbackStateInference.ts, 0, 0), Decl(promiseUnionCallbackStateInference.ts, 3, 14)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 4, 30)) + + action: (state: State, payload: string) => State | Promise, +>action : Symbol(action, Decl(promiseUnionCallbackStateInference.ts, 4, 37)) +>state : Symbol(state, Decl(promiseUnionCallbackStateInference.ts, 5, 13)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 4, 30)) +>payload : Symbol(payload, Decl(promiseUnionCallbackStateInference.ts, 5, 26)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 4, 30)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 4, 30)) + + initialState: State, +>initialState : Symbol(initialState, Decl(promiseUnionCallbackStateInference.ts, 5, 70)) +>State : Symbol(State, Decl(promiseUnionCallbackStateInference.ts, 4, 30)) + +): (payload: string) => void; +>payload : Symbol(payload, Decl(promiseUnionCallbackStateInference.ts, 7, 4)) + +declare const action: (previous: unknown, value: string) => Promise; +>action : Symbol(action, Decl(promiseUnionCallbackStateInference.ts, 9, 13)) +>previous : Symbol(previous, Decl(promiseUnionCallbackStateInference.ts, 9, 23)) +>value : Symbol(value, Decl(promiseUnionCallbackStateInference.ts, 9, 41)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +const dispatch = createAction(action, null); +>dispatch : Symbol(dispatch, Decl(promiseUnionCallbackStateInference.ts, 10, 5)) +>createAction : Symbol(createAction, Decl(promiseUnionCallbackStateInference.ts, 0, 0), Decl(promiseUnionCallbackStateInference.ts, 3, 14)) +>action : Symbol(action, Decl(promiseUnionCallbackStateInference.ts, 9, 13)) + +const bound = dispatch.bind(null, "value"); +>bound : Symbol(bound, Decl(promiseUnionCallbackStateInference.ts, 11, 5)) +>dispatch.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>dispatch : Symbol(dispatch, Decl(promiseUnionCallbackStateInference.ts, 10, 5)) +>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.types b/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.types new file mode 100644 index 0000000000000..dbe55252f676d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/promiseUnionCallbackStateInference.types @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/promiseUnionCallbackStateInference.ts] //// + +=== promiseUnionCallbackStateInference.ts === +declare function createAction( +>createAction : { (action: (state: State) => State | Promise, initialState: State): () => void; (action: (state: State_1, payload: string) => State_1 | Promise, initialState: State_1): (payload: string) => void; } + + action: (state: State) => State | Promise, +>action : (state: State) => State | Promise +>state : State + + initialState: State, +>initialState : State + +): () => void; +declare function createAction( +>createAction : { (action: (state: State_1) => State_1 | Promise, initialState: State_1): () => void; (action: (state: State, payload: string) => State | Promise, initialState: State): (payload: string) => void; } + + action: (state: State, payload: string) => State | Promise, +>action : (state: State, payload: string) => State | Promise +>state : State +>payload : string + + initialState: State, +>initialState : State + +): (payload: string) => void; +>payload : string + +declare const action: (previous: unknown, value: string) => Promise; +>action : (previous: unknown, value: string) => Promise +>previous : unknown +>value : string + +const dispatch = createAction(action, null); +>dispatch : (payload: string) => void +>createAction(action, null) : (payload: string) => void +>createAction : { (action: (state: State) => State | Promise, initialState: State): () => void; (action: (state: State, payload: string) => State | Promise, initialState: State): (payload: string) => void; } +>action : (previous: unknown, value: string) => Promise + +const bound = dispatch.bind(null, "value"); +>bound : () => void +>dispatch.bind(null, "value") : () => void +>dispatch.bind : { (this: T, thisArg: ThisParameterType): OmitThisParameter; (this: (this: T, ...args: [...A, ...B]) => R, thisArg: T, ...args: A): (...args: B) => R; } +>dispatch : (payload: string) => void +>bind : { (this: T, thisArg: ThisParameterType): OmitThisParameter; (this: (this: T, ...args: [...A, ...B]) => R, thisArg: T, ...args: A): (...args: B) => R; } +>"value" : "value" + diff --git a/tsc/testdata/tests/cases/compiler/promiseUnionCallbackStateInference.ts b/tsc/testdata/tests/cases/compiler/promiseUnionCallbackStateInference.ts new file mode 100644 index 0000000000000..33b15583d75e8 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/promiseUnionCallbackStateInference.ts @@ -0,0 +1,15 @@ +// @strict: true +// @target: es2015 + +declare function createAction( + action: (state: State) => State | Promise, + initialState: State, +): () => void; +declare function createAction( + action: (state: State, payload: string) => State | Promise, + initialState: State, +): (payload: string) => void; + +declare const action: (previous: unknown, value: string) => Promise; +const dispatch = createAction(action, null); +const bound = dispatch.bind(null, "value"); From 61c088020962c5dd1f3bd2d40467612a18d71af4 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 01:09:31 -0700 Subject: [PATCH 078/116] Add historical coverage: iterator nullish value assignment Characterize replacement of a nullish iterator value without narrowing its mutable receiver to the void return arm. The report-era primitive-discriminant experiment rejects this assignment, while the earlier iterator and impossible-branch baselines remain unchanged. Origins: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2529090675 https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2547278330 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../iteratorResultNullishValueAssignment.js | 17 ++++++++++++++ ...eratorResultNullishValueAssignment.symbols | 20 +++++++++++++++++ ...iteratorResultNullishValueAssignment.types | 22 +++++++++++++++++++ .../iteratorResultNullishValueAssignment.ts | 8 +++++++ 4 files changed, 67 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.js create mode 100644 tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.types create mode 100644 tsc/testdata/tests/cases/compiler/iteratorResultNullishValueAssignment.ts diff --git a/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.js b/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.js new file mode 100644 index 0000000000000..e0b72e5b3b7af --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/iteratorResultNullishValueAssignment.ts] //// + +//// [iteratorResultNullishValueAssignment.ts] +function initialize(result: IteratorResult) { + if (result.value == null) { + result.value = {}; + } +} + + +//// [iteratorResultNullishValueAssignment.js] +"use strict"; +function initialize(result) { + if (result.value == null) { + result.value = {}; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.symbols b/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.symbols new file mode 100644 index 0000000000000..18f2b09081255 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/iteratorResultNullishValueAssignment.ts] //// + +=== iteratorResultNullishValueAssignment.ts === +function initialize(result: IteratorResult) { +>initialize : Symbol(initialize, Decl(iteratorResultNullishValueAssignment.ts, 0, 0)) +>result : Symbol(result, Decl(iteratorResultNullishValueAssignment.ts, 0, 20)) +>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --)) + + if (result.value == null) { +>result.value : Symbol(value, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>result : Symbol(result, Decl(iteratorResultNullishValueAssignment.ts, 0, 20)) +>value : Symbol(value, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + result.value = {}; +>result.value : Symbol(value, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>result : Symbol(result, Decl(iteratorResultNullishValueAssignment.ts, 0, 20)) +>value : Symbol(value, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.types b/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.types new file mode 100644 index 0000000000000..bb9edfdf6c343 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/iteratorResultNullishValueAssignment.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/iteratorResultNullishValueAssignment.ts] //// + +=== iteratorResultNullishValueAssignment.ts === +function initialize(result: IteratorResult) { +>initialize : (result: IteratorResult) => void +>result : IteratorResult + + if (result.value == null) { +>result.value == null : boolean +>result.value : void | object +>result : IteratorResult +>value : void | object + + result.value = {}; +>result.value = {} : {} +>result.value : void | object +>result : IteratorResult +>value : void | object +>{} : {} + } +} + diff --git a/tsc/testdata/tests/cases/compiler/iteratorResultNullishValueAssignment.ts b/tsc/testdata/tests/cases/compiler/iteratorResultNullishValueAssignment.ts new file mode 100644 index 0000000000000..58f483f084149 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/iteratorResultNullishValueAssignment.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es2015 + +function initialize(result: IteratorResult) { + if (result.value == null) { + result.value = {}; + } +} From 6994b7fa199f8dbb67dadcf29cfc245cb101af28 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 01:59:08 -0700 Subject: [PATCH 079/116] Add historical coverage: explicit alwaysStrict false policy Characterize intentional alwaysStrict=false policy with false, true, and omitted-option CLI baselines. Authentic TS6 parent/head programs reproduce historical TS5107; current native TS7 asserts the later option-specific TS5108 removal, not literal prevention of that historical warning. Ordinary compiler fixtures skip this unsupported flag, so use the existing CLI baseline mechanism without changing the harness or implementation. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63089#issuecomment-3846213662 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- tsc/internal/execute/tsctests/tsc_test.go | 14 ++++++ .../alwaysStrict-false-in-configuration.js | 43 +++++++++++++++++++ .../alwaysStrict-omitted-in-configuration.js | 35 +++++++++++++++ .../alwaysStrict-true-in-configuration.js | 35 +++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-false-in-configuration.js create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-omitted-in-configuration.js create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-true-in-configuration.js diff --git a/tsc/internal/execute/tsctests/tsc_test.go b/tsc/internal/execute/tsctests/tsc_test.go index aff5f93620582..68c6127d5ecfb 100644 --- a/tsc/internal/execute/tsctests/tsc_test.go +++ b/tsc/internal/execute/tsctests/tsc_test.go @@ -282,6 +282,20 @@ func TestTscCommandline(t *testing.T) { }, } + for _, value := range []string{"false", "true", "omitted"} { + option := "" + if value != "omitted" { + option = `, "alwaysStrict": ` + value + } + testCases = append(testCases, &tscInput{ + subScenario: "alwaysStrict " + value + " in configuration", + files: FileMap{ + "/home/src/workspaces/project/tsconfig.json": fmt.Sprintf(`{"compilerOptions": {"target": "es2015"%s}}`, option), + "/home/src/workspaces/project/index.ts": "export {};", + }, + commandLineArgs: []string{"--noEmit"}, + }) + } for _, testCase := range testCases { testCase.run(t, "commandLine") } diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-false-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-false-in-configuration.js new file mode 100644 index 0000000000000..5bde982f5d622 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-false-in-configuration.js @@ -0,0 +1,43 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"compilerOptions": {"target": "es2015", "alwaysStrict": false}} + +tsgo --noEmit +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +tsconfig.json:1:58 - error TS5108: Option 'alwaysStrict=false' has been removed. Please remove it from your configuration. + +1 {"compilerOptions": {"target": "es2015", "alwaysStrict": false}} +   ~~~~~ + + +Found 1 error in tsconfig.json:1 + +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-omitted-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-omitted-in-configuration.js new file mode 100644 index 0000000000000..24091a7a513c3 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-omitted-in-configuration.js @@ -0,0 +1,35 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"compilerOptions": {"target": "es2015"}} + +tsgo --noEmit +ExitStatus:: Success +Output:: +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-true-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-true-in-configuration.js new file mode 100644 index 0000000000000..eb628f719d4b3 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/alwaysStrict-true-in-configuration.js @@ -0,0 +1,35 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"compilerOptions": {"target": "es2015", "alwaysStrict": true}} + +tsgo --noEmit +ExitStatus:: Success +Output:: +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + From 07df8ea2e5d29430b7432e5a9b6474b871b7ff3a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 02:31:23 -0700 Subject: [PATCH 080/116] Add historical coverage: nullable enum switch receiver Preserve direct enum-property access in an exhaustive default branch after an early null return. The final historical experiment narrows the object receiver to never, producing the reported property error and error-any assertNever argument cascade. Existing switch profiles remain unchanged; the generic impossible-property baseline detects the broader policy but lacks this nullable enum switch form. Original full-source flags retain fourteen unrelated library errors; clean historical minimal/current behavior is characterized without a compiler fix or original whole-build success claim. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2547278330 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../enumPropertyExhaustiveNullableReceiver.js | 33 ++++++++++++++ ...PropertyExhaustiveNullableReceiver.symbols | 44 ++++++++++++++++++ ...umPropertyExhaustiveNullableReceiver.types | 45 +++++++++++++++++++ .../enumPropertyExhaustiveNullableReceiver.ts | 15 +++++++ 4 files changed, 137 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.js create mode 100644 tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.types create mode 100644 tsc/testdata/tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts diff --git a/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.js b/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.js new file mode 100644 index 0000000000000..7f3edaded19f8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.js @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts] //// + +//// [enumPropertyExhaustiveNullableReceiver.ts] +enum NotificationKind { Review, Comment } + +declare function assertNever(value: never): never; + +function notify(notification: { kind: NotificationKind } | null) { + if (notification === null) return; + switch (notification.kind) { + case NotificationKind.Review: return; + case NotificationKind.Comment: return; + default: return assertNever(notification.kind); + } +} + + +//// [enumPropertyExhaustiveNullableReceiver.js] +"use strict"; +var NotificationKind; +(function (NotificationKind) { + NotificationKind[NotificationKind["Review"] = 0] = "Review"; + NotificationKind[NotificationKind["Comment"] = 1] = "Comment"; +})(NotificationKind || (NotificationKind = {})); +function notify(notification) { + if (notification === null) + return; + switch (notification.kind) { + case NotificationKind.Review: return; + case NotificationKind.Comment: return; + default: return assertNever(notification.kind); + } +} diff --git a/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.symbols b/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.symbols new file mode 100644 index 0000000000000..3f9767d7a894c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.symbols @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts] //// + +=== enumPropertyExhaustiveNullableReceiver.ts === +enum NotificationKind { Review, Comment } +>NotificationKind : Symbol(NotificationKind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 0)) +>Review : Symbol(NotificationKind.Review, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 23)) +>Comment : Symbol(NotificationKind.Comment, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 31)) + +declare function assertNever(value: never): never; +>assertNever : Symbol(assertNever, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 41)) +>value : Symbol(value, Decl(enumPropertyExhaustiveNullableReceiver.ts, 2, 29)) + +function notify(notification: { kind: NotificationKind } | null) { +>notify : Symbol(notify, Decl(enumPropertyExhaustiveNullableReceiver.ts, 2, 50)) +>notification : Symbol(notification, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 16)) +>kind : Symbol(kind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 31)) +>NotificationKind : Symbol(NotificationKind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 0)) + + if (notification === null) return; +>notification : Symbol(notification, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 16)) + + switch (notification.kind) { +>notification.kind : Symbol(kind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 31)) +>notification : Symbol(notification, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 16)) +>kind : Symbol(kind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 31)) + + case NotificationKind.Review: return; +>NotificationKind.Review : Symbol(NotificationKind.Review, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 23)) +>NotificationKind : Symbol(NotificationKind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 0)) +>Review : Symbol(NotificationKind.Review, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 23)) + + case NotificationKind.Comment: return; +>NotificationKind.Comment : Symbol(NotificationKind.Comment, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 31)) +>NotificationKind : Symbol(NotificationKind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 0)) +>Comment : Symbol(NotificationKind.Comment, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 31)) + + default: return assertNever(notification.kind); +>assertNever : Symbol(assertNever, Decl(enumPropertyExhaustiveNullableReceiver.ts, 0, 41)) +>notification.kind : Symbol(kind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 31)) +>notification : Symbol(notification, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 16)) +>kind : Symbol(kind, Decl(enumPropertyExhaustiveNullableReceiver.ts, 4, 31)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.types b/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.types new file mode 100644 index 0000000000000..6bfd58dbc6a0a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/enumPropertyExhaustiveNullableReceiver.types @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts] //// + +=== enumPropertyExhaustiveNullableReceiver.ts === +enum NotificationKind { Review, Comment } +>NotificationKind : NotificationKind +>Review : NotificationKind.Review +>Comment : NotificationKind.Comment + +declare function assertNever(value: never): never; +>assertNever : (value: never) => never +>value : never + +function notify(notification: { kind: NotificationKind } | null) { +>notify : (notification: { kind: NotificationKind; } | null) => undefined +>notification : { kind: NotificationKind; } | null +>kind : NotificationKind + + if (notification === null) return; +>notification === null : boolean +>notification : { kind: NotificationKind; } | null + + switch (notification.kind) { +>notification.kind : NotificationKind +>notification : { kind: NotificationKind; } +>kind : NotificationKind + + case NotificationKind.Review: return; +>NotificationKind.Review : NotificationKind.Review +>NotificationKind : typeof NotificationKind +>Review : NotificationKind.Review + + case NotificationKind.Comment: return; +>NotificationKind.Comment : NotificationKind.Comment +>NotificationKind : typeof NotificationKind +>Comment : NotificationKind.Comment + + default: return assertNever(notification.kind); +>assertNever(notification.kind) : never +>assertNever : (value: never) => never +>notification.kind : never +>notification : { kind: NotificationKind; } +>kind : never + } +} + diff --git a/tsc/testdata/tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts b/tsc/testdata/tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts new file mode 100644 index 0000000000000..87ccc45e7af83 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/enumPropertyExhaustiveNullableReceiver.ts @@ -0,0 +1,15 @@ +// @strict: true +// @target: es2015 + +enum NotificationKind { Review, Comment } + +declare function assertNever(value: never): never; + +function notify(notification: { kind: NotificationKind } | null) { + if (notification === null) return; + switch (notification.kind) { + case NotificationKind.Review: return; + case NotificationKind.Comment: return; + default: return assertNever(notification.kind); + } +} From 2a170359f6c97d9340a5ed4adf77d54e790c2503 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 03:55:15 -0700 Subject: [PATCH 081/116] Cover truthy re-reads of an undefined object property Characterize the current object receiver and never property after a truthiness check on an inferred undefined field. The unmerged non-union exhaustiveness experiment instead narrowed the receiver itself and reported TS2339. The reduced case needs no class, React contract, external library, or compiler change. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62114#issuecomment-3111469002 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../undefinedPropertyTruthyReceiver.js | 11 ++++++++++ .../undefinedPropertyTruthyReceiver.symbols | 17 ++++++++++++++++ .../undefinedPropertyTruthyReceiver.types | 20 +++++++++++++++++++ .../undefinedPropertyTruthyReceiver.ts | 4 ++++ 4 files changed, 52 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.js create mode 100644 tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.types create mode 100644 tsc/testdata/tests/cases/compiler/undefinedPropertyTruthyReceiver.ts diff --git a/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.js b/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.js new file mode 100644 index 0000000000000..a317eccb94e84 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.js @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/undefinedPropertyTruthyReceiver.ts] //// + +//// [undefinedPropertyTruthyReceiver.ts] +const state = { error: undefined }; +const renderedError = state.error ? state.error : ""; + + +//// [undefinedPropertyTruthyReceiver.js] +"use strict"; +const state = { error: undefined }; +const renderedError = state.error ? state.error : ""; diff --git a/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.symbols b/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.symbols new file mode 100644 index 0000000000000..fb40cbd4b9268 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/undefinedPropertyTruthyReceiver.ts] //// + +=== undefinedPropertyTruthyReceiver.ts === +const state = { error: undefined }; +>state : Symbol(state, Decl(undefinedPropertyTruthyReceiver.ts, 0, 5)) +>error : Symbol(error, Decl(undefinedPropertyTruthyReceiver.ts, 0, 15)) +>undefined : Symbol(undefined) + +const renderedError = state.error ? state.error : ""; +>renderedError : Symbol(renderedError, Decl(undefinedPropertyTruthyReceiver.ts, 1, 5)) +>state.error : Symbol(error, Decl(undefinedPropertyTruthyReceiver.ts, 0, 15)) +>state : Symbol(state, Decl(undefinedPropertyTruthyReceiver.ts, 0, 5)) +>error : Symbol(error, Decl(undefinedPropertyTruthyReceiver.ts, 0, 15)) +>state.error : Symbol(error, Decl(undefinedPropertyTruthyReceiver.ts, 0, 15)) +>state : Symbol(state, Decl(undefinedPropertyTruthyReceiver.ts, 0, 5)) +>error : Symbol(error, Decl(undefinedPropertyTruthyReceiver.ts, 0, 15)) + diff --git a/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.types b/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.types new file mode 100644 index 0000000000000..5f1307a448055 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/undefinedPropertyTruthyReceiver.types @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/undefinedPropertyTruthyReceiver.ts] //// + +=== undefinedPropertyTruthyReceiver.ts === +const state = { error: undefined }; +>state : { error: undefined; } +>{ error: undefined } : { error: undefined; } +>error : undefined +>undefined : undefined + +const renderedError = state.error ? state.error : ""; +>renderedError : "" +>state.error ? state.error : "" : "" +>state.error : undefined +>state : { error: undefined; } +>error : undefined +>state.error : never +>state : { error: undefined; } +>error : never +>"" : "" + diff --git a/tsc/testdata/tests/cases/compiler/undefinedPropertyTruthyReceiver.ts b/tsc/testdata/tests/cases/compiler/undefinedPropertyTruthyReceiver.ts new file mode 100644 index 0000000000000..c57cdbd2e5365 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/undefinedPropertyTruthyReceiver.ts @@ -0,0 +1,4 @@ +// @strict: true + +const state = { error: undefined }; +const renderedError = state.error ? state.error : ""; From f33913bfb08304c21998513a23f7650b4d96bde2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 04:28:08 -0700 Subject: [PATCH 082/116] Cover nullish fallbacks after correlated label narrowing Reduce the VS Code editor action label reports to a correlated union and a required alias on its string-label arm. Preserve the fallback property receiver rather than treating the right side as an invalid access on never. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2529090675 Repeated report: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2547278330 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../correlatedLabelNullishFallback.js | 14 ++++++++++ .../correlatedLabelNullishFallback.symbols | 23 ++++++++++++++++ .../correlatedLabelNullishFallback.types | 27 +++++++++++++++++++ .../correlatedLabelNullishFallback.ts | 5 ++++ 4 files changed, 69 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.js create mode 100644 tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.types create mode 100644 tsc/testdata/tests/cases/compiler/correlatedLabelNullishFallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.js b/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.js new file mode 100644 index 0000000000000..2b2fa870c17e6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.js @@ -0,0 +1,14 @@ +//// [tests/cases/compiler/correlatedLabelNullishFallback.ts] //// + +//// [correlatedLabelNullishFallback.ts] +function label(options: { label: string; alias: string } | { label: object; alias?: string }) { + if (typeof options.label === "string") return options.alias ?? options.label; +} + + +//// [correlatedLabelNullishFallback.js] +"use strict"; +function label(options) { + if (typeof options.label === "string") + return options.alias ?? options.label; +} diff --git a/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.symbols b/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.symbols new file mode 100644 index 0000000000000..93bf91eb9e082 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/correlatedLabelNullishFallback.ts] //// + +=== correlatedLabelNullishFallback.ts === +function label(options: { label: string; alias: string } | { label: object; alias?: string }) { +>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 0)) +>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15)) +>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25)) +>alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 40)) +>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 60)) +>alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 75)) + + if (typeof options.label === "string") return options.alias ?? options.label; +>options.label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60)) +>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15)) +>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60)) +>options.alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 40), Decl(correlatedLabelNullishFallback.ts, 0, 75)) +>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15)) +>alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 40), Decl(correlatedLabelNullishFallback.ts, 0, 75)) +>options.label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60)) +>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15)) +>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.types b/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.types new file mode 100644 index 0000000000000..a8a3a0a14e1c1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/correlatedLabelNullishFallback.types @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/correlatedLabelNullishFallback.ts] //// + +=== correlatedLabelNullishFallback.ts === +function label(options: { label: string; alias: string } | { label: object; alias?: string }) { +>label : (options: { label: string; alias: string; } | { label: object; alias?: string; }) => string | undefined +>options : { label: string; alias: string; } | { label: object; alias?: string; } +>label : string +>alias : string +>label : object +>alias : string | undefined + + if (typeof options.label === "string") return options.alias ?? options.label; +>typeof options.label === "string" : boolean +>typeof options.label : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>options.label : string | object +>options : { label: string; alias: string; } | { label: object; alias?: string; } +>label : string | object +>"string" : "string" +>options.alias ?? options.label : string +>options.alias : string | undefined +>options : { label: string; alias: string; } | { label: object; alias?: string; } +>alias : string | undefined +>options.label : string +>options : { label: string; alias: string; } | { label: object; alias?: string; } +>label : string +} + diff --git a/tsc/testdata/tests/cases/compiler/correlatedLabelNullishFallback.ts b/tsc/testdata/tests/cases/compiler/correlatedLabelNullishFallback.ts new file mode 100644 index 0000000000000..bdf2d4c085182 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/correlatedLabelNullishFallback.ts @@ -0,0 +1,5 @@ +// @strict: true + +function label(options: { label: string; alias: string } | { label: object; alias?: string }) { + if (typeof options.label === "string") return options.alias ?? options.label; +} From 15c4613ec9ba549d87100ad7b6f5462652b24c9b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 04:31:44 -0700 Subject: [PATCH 083/116] Cover non-strict optional-never result guards Reduce Continue GUI exclusive error/details result guards. Preserve the successful details access after the error-or-missing-details early return, without treating a nonempty string as an exhaustive error discriminant. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2529090675 Repeated report: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2547278330 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/nonStrictOptionalNeverResult.js | 17 ++++++++++ .../nonStrictOptionalNeverResult.symbols | 32 ++++++++++++++++++ .../nonStrictOptionalNeverResult.types | 33 +++++++++++++++++++ .../compiler/nonStrictOptionalNeverResult.ts | 7 ++++ 4 files changed, 89 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.js create mode 100644 tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.types create mode 100644 tsc/testdata/tests/cases/compiler/nonStrictOptionalNeverResult.ts diff --git a/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.js b/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.js new file mode 100644 index 0000000000000..a12077aeb3f87 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/nonStrictOptionalNeverResult.ts] //// + +//// [nonStrictOptionalNeverResult.ts] +type Result = { error: string; details?: never } | { details: { link: string }; error?: never }; +function read(result: Result) { + if (result.error || !result.details) return; + return result.details.link; +} + + +//// [nonStrictOptionalNeverResult.js] +"use strict"; +function read(result) { + if (result.error || !result.details) + return; + return result.details.link; +} diff --git a/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.symbols b/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.symbols new file mode 100644 index 0000000000000..3a159ce1ed91d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/nonStrictOptionalNeverResult.ts] //// + +=== nonStrictOptionalNeverResult.ts === +type Result = { error: string; details?: never } | { details: { link: string }; error?: never }; +>Result : Symbol(Result, Decl(nonStrictOptionalNeverResult.ts, 0, 0)) +>error : Symbol(error, Decl(nonStrictOptionalNeverResult.ts, 0, 15)) +>details : Symbol(details, Decl(nonStrictOptionalNeverResult.ts, 0, 30)) +>details : Symbol(details, Decl(nonStrictOptionalNeverResult.ts, 0, 52)) +>link : Symbol(link, Decl(nonStrictOptionalNeverResult.ts, 0, 63)) +>error : Symbol(error, Decl(nonStrictOptionalNeverResult.ts, 0, 79)) + +function read(result: Result) { +>read : Symbol(read, Decl(nonStrictOptionalNeverResult.ts, 0, 96)) +>result : Symbol(result, Decl(nonStrictOptionalNeverResult.ts, 1, 14)) +>Result : Symbol(Result, Decl(nonStrictOptionalNeverResult.ts, 0, 0)) + + if (result.error || !result.details) return; +>result.error : Symbol(error, Decl(nonStrictOptionalNeverResult.ts, 0, 15), Decl(nonStrictOptionalNeverResult.ts, 0, 79)) +>result : Symbol(result, Decl(nonStrictOptionalNeverResult.ts, 1, 14)) +>error : Symbol(error, Decl(nonStrictOptionalNeverResult.ts, 0, 15), Decl(nonStrictOptionalNeverResult.ts, 0, 79)) +>result.details : Symbol(details, Decl(nonStrictOptionalNeverResult.ts, 0, 30), Decl(nonStrictOptionalNeverResult.ts, 0, 52)) +>result : Symbol(result, Decl(nonStrictOptionalNeverResult.ts, 1, 14)) +>details : Symbol(details, Decl(nonStrictOptionalNeverResult.ts, 0, 30), Decl(nonStrictOptionalNeverResult.ts, 0, 52)) + + return result.details.link; +>result.details.link : Symbol(link, Decl(nonStrictOptionalNeverResult.ts, 0, 63)) +>result.details : Symbol(details, Decl(nonStrictOptionalNeverResult.ts, 0, 30), Decl(nonStrictOptionalNeverResult.ts, 0, 52)) +>result : Symbol(result, Decl(nonStrictOptionalNeverResult.ts, 1, 14)) +>details : Symbol(details, Decl(nonStrictOptionalNeverResult.ts, 0, 30), Decl(nonStrictOptionalNeverResult.ts, 0, 52)) +>link : Symbol(link, Decl(nonStrictOptionalNeverResult.ts, 0, 63)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.types b/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.types new file mode 100644 index 0000000000000..c1367a5a126dc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/nonStrictOptionalNeverResult.types @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/nonStrictOptionalNeverResult.ts] //// + +=== nonStrictOptionalNeverResult.ts === +type Result = { error: string; details?: never } | { details: { link: string }; error?: never }; +>Result : Result +>error : string +>details : never +>details : { link: string; } +>link : string +>error : never + +function read(result: Result) { +>read : (result: Result) => string +>result : Result + + if (result.error || !result.details) return; +>result.error || !result.details : string | boolean +>result.error : string +>result : Result +>error : string +>!result.details : boolean +>result.details : { link: string; } +>result : Result +>details : { link: string; } + + return result.details.link; +>result.details.link : string +>result.details : { link: string; } +>result : Result +>details : { link: string; } +>link : string +} + diff --git a/tsc/testdata/tests/cases/compiler/nonStrictOptionalNeverResult.ts b/tsc/testdata/tests/cases/compiler/nonStrictOptionalNeverResult.ts new file mode 100644 index 0000000000000..cf7f2c7951569 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/nonStrictOptionalNeverResult.ts @@ -0,0 +1,7 @@ +// @strict: false + +type Result = { error: string; details?: never } | { details: { link: string }; error?: never }; +function read(result: Result) { + if (result.error || !result.details) return; + return result.details.link; +} From 02466a3d09dc18432de0ddedfc2c7d823f2c3aee Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 04:44:15 -0700 Subject: [PATCH 084/116] Cover common-supertype inference through deep partial intersections Preserve callable nested properties when generic rest inference compares a concrete theme against its deep-partial customization. The authentic original experiment changes this clean case into TS2722 and TS2349; native inference remains clean. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63328#issuecomment-4164789350 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../partialDeepIntersectionCommonSupertype.js | 16 ++++++ ...ialDeepIntersectionCommonSupertype.symbols | 57 +++++++++++++++++++ ...rtialDeepIntersectionCommonSupertype.types | 42 ++++++++++++++ .../partialDeepIntersectionCommonSupertype.ts | 9 +++ 4 files changed, 124 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.js create mode 100644 tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.types create mode 100644 tsc/testdata/tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts diff --git a/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.js b/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.js new file mode 100644 index 0000000000000..e893270895b3f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts] //// + +//// [partialDeepIntersectionCommonSupertype.ts] +type PartialDeep = T extends object ? { [K in keyof T]?: PartialDeep } : T; +type Theme = T & { style: { message: (text: string) => string } }; +declare function makeTheme(...themes: PartialDeep>[]): Theme; +declare const theme: { style: { description: (text: string) => string } }; +declare const customization: PartialDeep>; +const merged = makeTheme(theme, customization); +merged.style.description(""); + + +//// [partialDeepIntersectionCommonSupertype.js] +"use strict"; +const merged = makeTheme(theme, customization); +merged.style.description(""); diff --git a/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.symbols b/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.symbols new file mode 100644 index 0000000000000..2deaff926d09c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.symbols @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts] //// + +=== partialDeepIntersectionCommonSupertype.ts === +type PartialDeep = T extends object ? { [K in keyof T]?: PartialDeep } : T; +>PartialDeep : Symbol(PartialDeep, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 0)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 17)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 17)) +>K : Symbol(K, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 44)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 17)) +>PartialDeep : Symbol(PartialDeep, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 0)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 17)) +>K : Symbol(K, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 44)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 17)) + +type Theme = T & { style: { message: (text: string) => string } }; +>Theme : Symbol(Theme, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 84)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 11)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 11)) +>style : Symbol(style, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 36)) +>message : Symbol(message, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 45)) +>text : Symbol(text, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 56)) + +declare function makeTheme(...themes: PartialDeep>[]): Theme; +>makeTheme : Symbol(makeTheme, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 84)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 2, 27)) +>themes : Symbol(themes, Decl(partialDeepIntersectionCommonSupertype.ts, 2, 45)) +>PartialDeep : Symbol(PartialDeep, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 0)) +>Theme : Symbol(Theme, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 84)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 2, 27)) +>Theme : Symbol(Theme, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 84)) +>T : Symbol(T, Decl(partialDeepIntersectionCommonSupertype.ts, 2, 27)) + +declare const theme: { style: { description: (text: string) => string } }; +>theme : Symbol(theme, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 13)) +>style : Symbol(style, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 22)) +>description : Symbol(description, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 31)) +>text : Symbol(text, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 46)) + +declare const customization: PartialDeep>; +>customization : Symbol(customization, Decl(partialDeepIntersectionCommonSupertype.ts, 4, 13)) +>PartialDeep : Symbol(PartialDeep, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 0)) +>Theme : Symbol(Theme, Decl(partialDeepIntersectionCommonSupertype.ts, 0, 84)) +>theme : Symbol(theme, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 13)) + +const merged = makeTheme(theme, customization); +>merged : Symbol(merged, Decl(partialDeepIntersectionCommonSupertype.ts, 5, 5)) +>makeTheme : Symbol(makeTheme, Decl(partialDeepIntersectionCommonSupertype.ts, 1, 84)) +>theme : Symbol(theme, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 13)) +>customization : Symbol(customization, Decl(partialDeepIntersectionCommonSupertype.ts, 4, 13)) + +merged.style.description(""); +>merged.style.description : Symbol(description, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 31)) +>merged.style : Symbol(style, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 22), Decl(partialDeepIntersectionCommonSupertype.ts, 1, 36)) +>merged : Symbol(merged, Decl(partialDeepIntersectionCommonSupertype.ts, 5, 5)) +>style : Symbol(style, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 22), Decl(partialDeepIntersectionCommonSupertype.ts, 1, 36)) +>description : Symbol(description, Decl(partialDeepIntersectionCommonSupertype.ts, 3, 31)) + diff --git a/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.types b/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.types new file mode 100644 index 0000000000000..4e516fcb682f1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/partialDeepIntersectionCommonSupertype.types @@ -0,0 +1,42 @@ +//// [tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts] //// + +=== partialDeepIntersectionCommonSupertype.ts === +type PartialDeep = T extends object ? { [K in keyof T]?: PartialDeep } : T; +>PartialDeep : PartialDeep + +type Theme = T & { style: { message: (text: string) => string } }; +>Theme : Theme +>style : { message: (text: string) => string; } +>message : (text: string) => string +>text : string + +declare function makeTheme(...themes: PartialDeep>[]): Theme; +>makeTheme : (...themes: PartialDeep>[]) => Theme +>themes : PartialDeep>[] + +declare const theme: { style: { description: (text: string) => string } }; +>theme : { style: { description: (text: string) => string; }; } +>style : { description: (text: string) => string; } +>description : (text: string) => string +>text : string + +declare const customization: PartialDeep>; +>customization : { style?: { message?: {} | undefined; description?: {} | undefined; } | undefined; } +>theme : { style: { description: (text: string) => string; }; } + +const merged = makeTheme(theme, customization); +>merged : Theme<{ style: { description: (text: string) => string; }; }> +>makeTheme(theme, customization) : Theme<{ style: { description: (text: string) => string; }; }> +>makeTheme : (...themes: PartialDeep>[]) => Theme +>theme : { style: { description: (text: string) => string; }; } +>customization : { style?: { message?: {} | undefined; description?: {} | undefined; } | undefined; } + +merged.style.description(""); +>merged.style.description("") : string +>merged.style.description : (text: string) => string +>merged.style : { description: (text: string) => string; } & { message: (text: string) => string; } +>merged : Theme<{ style: { description: (text: string) => string; }; }> +>style : { description: (text: string) => string; } & { message: (text: string) => string; } +>description : (text: string) => string +>"" : "" + diff --git a/tsc/testdata/tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts b/tsc/testdata/tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts new file mode 100644 index 0000000000000..8464824f475ee --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/partialDeepIntersectionCommonSupertype.ts @@ -0,0 +1,9 @@ +// @strict: true + +type PartialDeep = T extends object ? { [K in keyof T]?: PartialDeep } : T; +type Theme = T & { style: { message: (text: string) => string } }; +declare function makeTheme(...themes: PartialDeep>[]): Theme; +declare const theme: { style: { description: (text: string) => string } }; +declare const customization: PartialDeep>; +const merged = makeTheme(theme, customization); +merged.style.description(""); From 3dc1c33dad82ec0bdd803b8993b7c3d08c9ecd08 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 05:31:51 -0700 Subject: [PATCH 085/116] Cover loop inference through nullable array metadata Reduce the final PR60718 VS Code Monarch failure to a loop-carried inference cycle involving nullable array metadata, an inferred group entry, and an array-length comparison. Preserve the clean historical base and current native behavior without imports, SDK declarations, assertions, or compiler changes. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60718#issuecomment-2547278330 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/loopArrayLengthInferenceCycle.js | 40 +++++++++++ .../loopArrayLengthInferenceCycle.symbols | 54 +++++++++++++++ .../loopArrayLengthInferenceCycle.types | 66 +++++++++++++++++++ .../compiler/loopArrayLengthInferenceCycle.ts | 18 +++++ 4 files changed, 178 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.js create mode 100644 tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.types create mode 100644 tsc/testdata/tests/cases/compiler/loopArrayLengthInferenceCycle.ts diff --git a/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.js b/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.js new file mode 100644 index 0000000000000..e20746cf785b2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.js @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/loopArrayLengthInferenceCycle.ts] //// + +//// [loopArrayLengthInferenceCycle.ts] +function tokenize() { + let state: { matches: string[]; groups: string[][] } | null = null; + while (true) { + let matches: string[] | null = null; + let action: string[] | null = null; + if (state) { + const groupEntry = state.groups[0]; + action = groupEntry; + } + matches = []; + if (action) { + if (matches.length !== action.length) throw new Error(); + state = { matches, groups: [] }; + } + } +} + + +//// [loopArrayLengthInferenceCycle.js] +"use strict"; +function tokenize() { + let state = null; + while (true) { + let matches = null; + let action = null; + if (state) { + const groupEntry = state.groups[0]; + action = groupEntry; + } + matches = []; + if (action) { + if (matches.length !== action.length) + throw new Error(); + state = { matches, groups: [] }; + } + } +} diff --git a/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.symbols b/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.symbols new file mode 100644 index 0000000000000..fa63f3ace005e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.symbols @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/loopArrayLengthInferenceCycle.ts] //// + +=== loopArrayLengthInferenceCycle.ts === +function tokenize() { +>tokenize : Symbol(tokenize, Decl(loopArrayLengthInferenceCycle.ts, 0, 0)) + + let state: { matches: string[]; groups: string[][] } | null = null; +>state : Symbol(state, Decl(loopArrayLengthInferenceCycle.ts, 1, 7)) +>matches : Symbol(matches, Decl(loopArrayLengthInferenceCycle.ts, 1, 16)) +>groups : Symbol(groups, Decl(loopArrayLengthInferenceCycle.ts, 1, 35)) + + while (true) { + let matches: string[] | null = null; +>matches : Symbol(matches, Decl(loopArrayLengthInferenceCycle.ts, 3, 11)) + + let action: string[] | null = null; +>action : Symbol(action, Decl(loopArrayLengthInferenceCycle.ts, 4, 11)) + + if (state) { +>state : Symbol(state, Decl(loopArrayLengthInferenceCycle.ts, 1, 7)) + + const groupEntry = state.groups[0]; +>groupEntry : Symbol(groupEntry, Decl(loopArrayLengthInferenceCycle.ts, 6, 17)) +>state.groups : Symbol(groups, Decl(loopArrayLengthInferenceCycle.ts, 1, 35)) +>state : Symbol(state, Decl(loopArrayLengthInferenceCycle.ts, 1, 7)) +>groups : Symbol(groups, Decl(loopArrayLengthInferenceCycle.ts, 1, 35)) + + action = groupEntry; +>action : Symbol(action, Decl(loopArrayLengthInferenceCycle.ts, 4, 11)) +>groupEntry : Symbol(groupEntry, Decl(loopArrayLengthInferenceCycle.ts, 6, 17)) + } + matches = []; +>matches : Symbol(matches, Decl(loopArrayLengthInferenceCycle.ts, 3, 11)) + + if (action) { +>action : Symbol(action, Decl(loopArrayLengthInferenceCycle.ts, 4, 11)) + + if (matches.length !== action.length) throw new Error(); +>matches.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>matches : Symbol(matches, Decl(loopArrayLengthInferenceCycle.ts, 3, 11)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>action.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>action : Symbol(action, Decl(loopArrayLengthInferenceCycle.ts, 4, 11)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + state = { matches, groups: [] }; +>state : Symbol(state, Decl(loopArrayLengthInferenceCycle.ts, 1, 7)) +>matches : Symbol(matches, Decl(loopArrayLengthInferenceCycle.ts, 12, 21)) +>groups : Symbol(groups, Decl(loopArrayLengthInferenceCycle.ts, 12, 30)) + } + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.types b/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.types new file mode 100644 index 0000000000000..48dd02ad26532 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/loopArrayLengthInferenceCycle.types @@ -0,0 +1,66 @@ +//// [tests/cases/compiler/loopArrayLengthInferenceCycle.ts] //// + +=== loopArrayLengthInferenceCycle.ts === +function tokenize() { +>tokenize : () => void + + let state: { matches: string[]; groups: string[][] } | null = null; +>state : { matches: string[]; groups: string[][]; } | null +>matches : string[] +>groups : string[][] + + while (true) { +>true : true + + let matches: string[] | null = null; +>matches : string[] | null + + let action: string[] | null = null; +>action : string[] | null + + if (state) { +>state : { matches: string[]; groups: string[][]; } | null + + const groupEntry = state.groups[0]; +>groupEntry : string[] +>state.groups[0] : string[] +>state.groups : string[][] +>state : { matches: string[]; groups: string[][]; } +>groups : string[][] +>0 : 0 + + action = groupEntry; +>action = groupEntry : string[] +>action : string[] | null +>groupEntry : string[] + } + matches = []; +>matches = [] : never[] +>matches : string[] | null +>[] : never[] + + if (action) { +>action : string[] | null + + if (matches.length !== action.length) throw new Error(); +>matches.length !== action.length : boolean +>matches.length : number +>matches : string[] +>length : number +>action.length : number +>action : string[] +>length : number +>new Error() : Error +>Error : ErrorConstructor + + state = { matches, groups: [] }; +>state = { matches, groups: [] } : { matches: string[]; groups: never[]; } +>state : { matches: string[]; groups: string[][]; } | null +>{ matches, groups: [] } : { matches: string[]; groups: never[]; } +>matches : string[] +>groups : never[] +>[] : never[] + } + } +} + diff --git a/tsc/testdata/tests/cases/compiler/loopArrayLengthInferenceCycle.ts b/tsc/testdata/tests/cases/compiler/loopArrayLengthInferenceCycle.ts new file mode 100644 index 0000000000000..e444487b2a784 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/loopArrayLengthInferenceCycle.ts @@ -0,0 +1,18 @@ +// @strict: true + +function tokenize() { + let state: { matches: string[]; groups: string[][] } | null = null; + while (true) { + let matches: string[] | null = null; + let action: string[] | null = null; + if (state) { + const groupEntry = state.groups[0]; + action = groupEntry; + } + matches = []; + if (action) { + if (matches.length !== action.length) throw new Error(); + state = { matches, groups: [] }; + } + } +} From ee2e21a4c4685dd5d459dd8f3ce59dcd0f381efc Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 05:58:25 -0700 Subject: [PATCH 086/116] Cover baseUrl removal in parsed configurations Characterize intentional option policy with relative, JSON-empty, inherited, and omitted configurations in the existing CLI baseline table. Historical branch compilers reproduce TS5101; modern TS5102 is later removal-policy characterization, not literal historical diagnostic preservation. https://redirect.github.com/microsoft/TypeScript/pull/62432#issuecomment-3277144553 https://redirect.github.com/microsoft/TypeScript/pull/62432#issuecomment-3277144597 https://redirect.github.com/microsoft/TypeScript/pull/62432#issuecomment-3277144619 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- tsc/internal/execute/tsctests/tsc_test.go | 23 ++++++++++ .../baseUrl-empty-in-configuration.js | 44 +++++++++++++++++++ .../baseUrl-inherited-in-configuration.js | 42 ++++++++++++++++++ .../baseUrl-omitted-in-configuration.js | 35 +++++++++++++++ .../baseUrl-relative-in-configuration.js | 44 +++++++++++++++++++ 5 files changed, 188 insertions(+) create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-empty-in-configuration.js create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-inherited-in-configuration.js create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-omitted-in-configuration.js create mode 100644 tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-relative-in-configuration.js diff --git a/tsc/internal/execute/tsctests/tsc_test.go b/tsc/internal/execute/tsctests/tsc_test.go index 68c6127d5ecfb..c5f7c8c43d779 100644 --- a/tsc/internal/execute/tsctests/tsc_test.go +++ b/tsc/internal/execute/tsctests/tsc_test.go @@ -296,6 +296,29 @@ func TestTscCommandline(t *testing.T) { commandLineArgs: []string{"--noEmit"}, }) } + for _, setting := range []struct { + name string + config string + base string + }{ + {"relative", `{"compilerOptions": {"target": "es2015", "baseUrl": "."}}`, ""}, + {"empty", `{"compilerOptions": {"target": "es2015", "baseUrl": ""}}`, ""}, + {"inherited", `{"extends": "./base.json"}`, `{"compilerOptions": {"target": "es2015", "baseUrl": "."}}`}, + {"omitted", `{"compilerOptions": {"target": "es2015"}}`, ""}, + } { + files := FileMap{ + "/home/src/workspaces/project/tsconfig.json": setting.config, + "/home/src/workspaces/project/index.ts": "export {};", + } + if setting.base != "" { + files["/home/src/workspaces/project/base.json"] = setting.base + } + testCases = append(testCases, &tscInput{ + subScenario: "baseUrl " + setting.name + " in configuration", + files: files, + commandLineArgs: []string{"--noEmit"}, + }) + } for _, testCase := range testCases { testCase.run(t, "commandLine") } diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-empty-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-empty-in-configuration.js new file mode 100644 index 0000000000000..f991baa6f927c --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-empty-in-configuration.js @@ -0,0 +1,44 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"compilerOptions": {"target": "es2015", "baseUrl": ""}} + +tsgo --noEmit +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +tsconfig.json:1:42 - error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration. + Use '"paths": {"*": ["./*"]}' instead. + +1 {"compilerOptions": {"target": "es2015", "baseUrl": ""}} +   ~~~~~~~~~ + + +Found 1 error in tsconfig.json:1 + +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-inherited-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-inherited-in-configuration.js new file mode 100644 index 0000000000000..417c0846c9579 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-inherited-in-configuration.js @@ -0,0 +1,42 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/base.json] *new* +{"compilerOptions": {"target": "es2015", "baseUrl": "."}} +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"extends": "./base.json"} + +tsgo --noEmit +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration. + Use '"paths": {"*": ["./*"]}' instead. + +Found 1 error. + +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-omitted-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-omitted-in-configuration.js new file mode 100644 index 0000000000000..24091a7a513c3 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-omitted-in-configuration.js @@ -0,0 +1,35 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"compilerOptions": {"target": "es2015"}} + +tsgo --noEmit +ExitStatus:: Success +Output:: +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-relative-in-configuration.js b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-relative-in-configuration.js new file mode 100644 index 0000000000000..62b45462fc098 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/commandLine/baseUrl-relative-in-configuration.js @@ -0,0 +1,44 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/index.ts] *new* +export {}; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"compilerOptions": {"target": "es2015", "baseUrl": "."}} + +tsgo --noEmit +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +tsconfig.json:1:42 - error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration. + Use '"paths": {"*": ["./*"]}' instead. + +1 {"compilerOptions": {"target": "es2015", "baseUrl": "."}} +   ~~~~~~~~~ + + +Found 1 error in tsconfig.json:1 + +//// [/home/src/tslibs/TS/Lib/lib.es6.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; + From 5d324d827eaa3121d7002f5267e4235d706139ad Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 07:03:10 -0700 Subject: [PATCH 087/116] Cover distinct defaults behind type-only export stars Add a self-contained type-only star collision profile. Exact original PR base is clean, the open default-star proposal adds TS2308 at the second star, and the current compiler remains clean. The original proposal tests a single type-only default re-export, not ambiguity between two type-only stars. Origin: https://redirect.github.com/microsoft/TypeScript/pull/64745#issuecomment-6121296640 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/typeOnlyStarDefaultCollision.js | 19 +++++++++++++++++++ .../typeOnlyStarDefaultCollision.symbols | 15 +++++++++++++++ .../typeOnlyStarDefaultCollision.types | 15 +++++++++++++++ .../compiler/typeOnlyStarDefaultCollision.ts | 12 ++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.js create mode 100644 tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.types create mode 100644 tsc/testdata/tests/cases/compiler/typeOnlyStarDefaultCollision.ts diff --git a/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.js b/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.js new file mode 100644 index 0000000000000..6da804d8b3fa0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/typeOnlyStarDefaultCollision.ts] //// + +//// [first.ts] +export default 1; + +//// [second.ts] +export default 2; + +//// [barrel.ts] +export type * from "./first"; +export type * from "./second"; + + +//// [first.js] +export default 1; +//// [second.js] +export default 2; +//// [barrel.js] +export {}; diff --git a/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.symbols b/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.symbols new file mode 100644 index 0000000000000..2e8746d8e7772 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/typeOnlyStarDefaultCollision.ts] //// + +=== first.ts === + +export default 1; + +=== second.ts === + +export default 2; + +=== barrel.ts === + +export type * from "./first"; +export type * from "./second"; + diff --git a/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.types b/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.types new file mode 100644 index 0000000000000..2e8746d8e7772 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/typeOnlyStarDefaultCollision.types @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/typeOnlyStarDefaultCollision.ts] //// + +=== first.ts === + +export default 1; + +=== second.ts === + +export default 2; + +=== barrel.ts === + +export type * from "./first"; +export type * from "./second"; + diff --git a/tsc/testdata/tests/cases/compiler/typeOnlyStarDefaultCollision.ts b/tsc/testdata/tests/cases/compiler/typeOnlyStarDefaultCollision.ts new file mode 100644 index 0000000000000..bdfe17a17448c --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/typeOnlyStarDefaultCollision.ts @@ -0,0 +1,12 @@ +// @target: es2015 +// @module: esnext + +// @filename: first.ts +export default 1; + +// @filename: second.ts +export default 2; + +// @filename: barrel.ts +export type * from "./first"; +export type * from "./second"; From 3825176e28a16f96d5ee61dde0045089ddc8d3ac Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 07:03:14 -0700 Subject: [PATCH 088/116] Cover export-star ambiguity between local default bindings Retain two local default-export assignments rather than the original proposal fixture's directly declared default classes. Authentic original base is clean, proposal head adds TS2308, and current JS/type/symbol snapshots remain clean. No downstream library or SDK is imported. Origin: https://redirect.github.com/microsoft/TypeScript/pull/64745#issuecomment-6121296640 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../starDefaultAssignmentCollision.js | 24 +++++++++++++++++++ .../starDefaultAssignmentCollision.symbols | 21 ++++++++++++++++ .../starDefaultAssignmentCollision.types | 23 ++++++++++++++++++ .../starDefaultAssignmentCollision.ts | 14 +++++++++++ 4 files changed, 82 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.js create mode 100644 tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.types create mode 100644 tsc/testdata/tests/cases/compiler/starDefaultAssignmentCollision.ts diff --git a/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.js b/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.js new file mode 100644 index 0000000000000..014733382b169 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/starDefaultAssignmentCollision.ts] //// + +//// [first.ts] +const first = 1; +export default first; + +//// [second.ts] +const second = 2; +export default second; + +//// [barrel.ts] +export * from "./first"; +export * from "./second"; + + +//// [first.js] +const first = 1; +export default first; +//// [second.js] +const second = 2; +export default second; +//// [barrel.js] +export * from "./first"; +export * from "./second"; diff --git a/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.symbols b/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.symbols new file mode 100644 index 0000000000000..9fe4d08343619 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/starDefaultAssignmentCollision.ts] //// + +=== first.ts === +const first = 1; +>first : Symbol(first, Decl(first.ts, 0, 5)) + +export default first; +>first : Symbol(first, Decl(first.ts, 0, 5)) + +=== second.ts === +const second = 2; +>second : Symbol(second, Decl(second.ts, 0, 5)) + +export default second; +>second : Symbol(second, Decl(second.ts, 0, 5)) + +=== barrel.ts === + +export * from "./first"; +export * from "./second"; + diff --git a/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.types b/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.types new file mode 100644 index 0000000000000..5d58137acde51 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/starDefaultAssignmentCollision.types @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/starDefaultAssignmentCollision.ts] //// + +=== first.ts === +const first = 1; +>first : 1 +>1 : 1 + +export default first; +>first : 1 + +=== second.ts === +const second = 2; +>second : 2 +>2 : 2 + +export default second; +>second : 2 + +=== barrel.ts === + +export * from "./first"; +export * from "./second"; + diff --git a/tsc/testdata/tests/cases/compiler/starDefaultAssignmentCollision.ts b/tsc/testdata/tests/cases/compiler/starDefaultAssignmentCollision.ts new file mode 100644 index 0000000000000..f9485e4cebf97 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/starDefaultAssignmentCollision.ts @@ -0,0 +1,14 @@ +// @target: es2015 +// @module: esnext + +// @filename: first.ts +const first = 1; +export default first; + +// @filename: second.ts +const second = 2; +export default second; + +// @filename: barrel.ts +export * from "./first"; +export * from "./second"; From e3f6a35b893108f7053f8438fd3ef01df7bda1ab Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 07:03:18 -0700 Subject: [PATCH 089/116] Cover distinct defaults through a transitive export star Keep one nested star hop before the conflicting star. Authentic original base is clean, proposal head adds TS2308, and current snapshots remain clean. Independently replayed same-symbol and explicit-default controls stay clean; selected original source/config proofs are not claimed full downstream builds. Origin: https://redirect.github.com/microsoft/TypeScript/pull/64745#issuecomment-6121296640 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../transitiveStarDefaultCollision.js | 25 +++++++++++++++++++ .../transitiveStarDefaultCollision.symbols | 19 ++++++++++++++ .../transitiveStarDefaultCollision.types | 19 ++++++++++++++ .../transitiveStarDefaultCollision.ts | 15 +++++++++++ 4 files changed, 78 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.js create mode 100644 tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.types create mode 100644 tsc/testdata/tests/cases/compiler/transitiveStarDefaultCollision.ts diff --git a/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.js b/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.js new file mode 100644 index 0000000000000..10719dd7987c6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/transitiveStarDefaultCollision.ts] //// + +//// [first.ts] +export default 1; + +//// [second.ts] +export default 2; + +//// [nested.ts] +export * from "./first"; + +//// [barrel.ts] +export * from "./nested"; +export * from "./second"; + + +//// [first.js] +export default 1; +//// [second.js] +export default 2; +//// [nested.js] +export * from "./first"; +//// [barrel.js] +export * from "./nested"; +export * from "./second"; diff --git a/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.symbols b/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.symbols new file mode 100644 index 0000000000000..418fbd888d8f5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/transitiveStarDefaultCollision.ts] //// + +=== first.ts === + +export default 1; + +=== second.ts === + +export default 2; + +=== nested.ts === + +export * from "./first"; + +=== barrel.ts === + +export * from "./nested"; +export * from "./second"; + diff --git a/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.types b/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.types new file mode 100644 index 0000000000000..418fbd888d8f5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/transitiveStarDefaultCollision.types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/transitiveStarDefaultCollision.ts] //// + +=== first.ts === + +export default 1; + +=== second.ts === + +export default 2; + +=== nested.ts === + +export * from "./first"; + +=== barrel.ts === + +export * from "./nested"; +export * from "./second"; + diff --git a/tsc/testdata/tests/cases/compiler/transitiveStarDefaultCollision.ts b/tsc/testdata/tests/cases/compiler/transitiveStarDefaultCollision.ts new file mode 100644 index 0000000000000..3a0bd711d919e --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/transitiveStarDefaultCollision.ts @@ -0,0 +1,15 @@ +// @target: es2015 +// @module: esnext + +// @filename: first.ts +export default 1; + +// @filename: second.ts +export default 2; + +// @filename: nested.ts +export * from "./first"; + +// @filename: barrel.ts +export * from "./nested"; +export * from "./second"; From 69a3b6c1384b473f1cb0d4d4f4a986a4db159223 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 08:25:42 -0700 Subject: [PATCH 090/116] Cover array-shaped DOM observer callbacks Capture contextual numeric indexing, array methods and element typing in the genuine ResizeObserver, MutationObserver and IntersectionObserver callbacks. The original unmerged Iterable experiment rejects these forms; current array contracts remain clean. https://redirect.github.com/microsoft/TypeScript/pull/63193#issuecomment-3963099870 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/domObserverArrayCallbacks.js | 13 ++++++ .../domObserverArrayCallbacks.symbols | 30 +++++++++++++ .../compiler/domObserverArrayCallbacks.types | 44 +++++++++++++++++++ .../compiler/domObserverArrayCallbacks.ts | 7 +++ 4 files changed, 94 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.js create mode 100644 tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.types create mode 100644 tsc/testdata/tests/cases/compiler/domObserverArrayCallbacks.ts diff --git a/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.js b/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.js new file mode 100644 index 0000000000000..314cadd4dbbf3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/domObserverArrayCallbacks.ts] //// + +//// [domObserverArrayCallbacks.ts] +new ResizeObserver(entries => entries[0]); +new MutationObserver(records => records.some(record => record.attributeName === "style")); +new IntersectionObserver(entries => entries.forEach(entry => entry.isIntersecting)); + + +//// [domObserverArrayCallbacks.js] +"use strict"; +new ResizeObserver(entries => entries[0]); +new MutationObserver(records => records.some(record => record.attributeName === "style")); +new IntersectionObserver(entries => entries.forEach(entry => entry.isIntersecting)); diff --git a/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.symbols b/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.symbols new file mode 100644 index 0000000000000..411f157f153e0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.symbols @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/domObserverArrayCallbacks.ts] //// + +=== domObserverArrayCallbacks.ts === +new ResizeObserver(entries => entries[0]); +>ResizeObserver : Symbol(ResizeObserver, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>entries : Symbol(entries, Decl(domObserverArrayCallbacks.ts, 0, 19)) +>entries : Symbol(entries, Decl(domObserverArrayCallbacks.ts, 0, 19)) + +new MutationObserver(records => records.some(record => record.attributeName === "style")); +>MutationObserver : Symbol(MutationObserver, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>records : Symbol(records, Decl(domObserverArrayCallbacks.ts, 1, 21)) +>records.some : Symbol(Array.some, Decl(lib.es5.d.ts, --, --)) +>records : Symbol(records, Decl(domObserverArrayCallbacks.ts, 1, 21)) +>some : Symbol(Array.some, Decl(lib.es5.d.ts, --, --)) +>record : Symbol(record, Decl(domObserverArrayCallbacks.ts, 1, 45)) +>record.attributeName : Symbol(MutationRecord.attributeName, Decl(lib.dom.d.ts, --, --)) +>record : Symbol(record, Decl(domObserverArrayCallbacks.ts, 1, 45)) +>attributeName : Symbol(MutationRecord.attributeName, Decl(lib.dom.d.ts, --, --)) + +new IntersectionObserver(entries => entries.forEach(entry => entry.isIntersecting)); +>IntersectionObserver : Symbol(IntersectionObserver, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>entries : Symbol(entries, Decl(domObserverArrayCallbacks.ts, 2, 25)) +>entries.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(entries, Decl(domObserverArrayCallbacks.ts, 2, 25)) +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>entry : Symbol(entry, Decl(domObserverArrayCallbacks.ts, 2, 52)) +>entry.isIntersecting : Symbol(IntersectionObserverEntry.isIntersecting, Decl(lib.dom.d.ts, --, --)) +>entry : Symbol(entry, Decl(domObserverArrayCallbacks.ts, 2, 52)) +>isIntersecting : Symbol(IntersectionObserverEntry.isIntersecting, Decl(lib.dom.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.types b/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.types new file mode 100644 index 0000000000000..8613637947dcc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domObserverArrayCallbacks.types @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/domObserverArrayCallbacks.ts] //// + +=== domObserverArrayCallbacks.ts === +new ResizeObserver(entries => entries[0]); +>new ResizeObserver(entries => entries[0]) : ResizeObserver +>ResizeObserver : { new (callback: ResizeObserverCallback): ResizeObserver; prototype: ResizeObserver; } +>entries => entries[0] : (entries: ResizeObserverEntry[]) => ResizeObserverEntry +>entries : ResizeObserverEntry[] +>entries[0] : ResizeObserverEntry +>entries : ResizeObserverEntry[] +>0 : 0 + +new MutationObserver(records => records.some(record => record.attributeName === "style")); +>new MutationObserver(records => records.some(record => record.attributeName === "style")) : MutationObserver +>MutationObserver : { new (callback: MutationCallback): MutationObserver; prototype: MutationObserver; } +>records => records.some(record => record.attributeName === "style") : (records: MutationRecord[]) => boolean +>records : MutationRecord[] +>records.some(record => record.attributeName === "style") : boolean +>records.some : (predicate: (value: MutationRecord, index: number, array: MutationRecord[]) => unknown, thisArg?: any) => boolean +>records : MutationRecord[] +>some : (predicate: (value: MutationRecord, index: number, array: MutationRecord[]) => unknown, thisArg?: any) => boolean +>record => record.attributeName === "style" : (record: MutationRecord) => boolean +>record : MutationRecord +>record.attributeName === "style" : boolean +>record.attributeName : string | null +>record : MutationRecord +>attributeName : string | null +>"style" : "style" + +new IntersectionObserver(entries => entries.forEach(entry => entry.isIntersecting)); +>new IntersectionObserver(entries => entries.forEach(entry => entry.isIntersecting)) : IntersectionObserver +>IntersectionObserver : { new (callback: IntersectionObserverCallback, options?: IntersectionObserverInit): IntersectionObserver; prototype: IntersectionObserver; } +>entries => entries.forEach(entry => entry.isIntersecting) : (entries: IntersectionObserverEntry[]) => void +>entries : IntersectionObserverEntry[] +>entries.forEach(entry => entry.isIntersecting) : void +>entries.forEach : (callbackfn: (value: IntersectionObserverEntry, index: number, array: IntersectionObserverEntry[]) => void, thisArg?: any) => void +>entries : IntersectionObserverEntry[] +>forEach : (callbackfn: (value: IntersectionObserverEntry, index: number, array: IntersectionObserverEntry[]) => void, thisArg?: any) => void +>entry => entry.isIntersecting : (entry: IntersectionObserverEntry) => boolean +>entry : IntersectionObserverEntry +>entry.isIntersecting : boolean +>entry : IntersectionObserverEntry +>isIntersecting : boolean + diff --git a/tsc/testdata/tests/cases/compiler/domObserverArrayCallbacks.ts b/tsc/testdata/tests/cases/compiler/domObserverArrayCallbacks.ts new file mode 100644 index 0000000000000..706f124c5fd0c --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domObserverArrayCallbacks.ts @@ -0,0 +1,7 @@ +// @strict: true +// @target: es2015 +// @lib: es2015,dom + +new ResizeObserver(entries => entries[0]); +new MutationObserver(records => records.some(record => record.attributeName === "style")); +new IntersectionObserver(entries => entries.forEach(entry => entry.isIntersecting)); From 0ef20711693d42e13e00821f85ea43d7d9ae9e4d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 08:25:46 -0700 Subject: [PATCH 091/116] Cover explicitly typed ResizeObserver callbacks Capture the narrower explicitly annotated ResizeObserverEntry[] callback, including strict callback parameter variance. The original unmerged Iterable experiment rejects this form; the current DOM callback accepts it. https://redirect.github.com/microsoft/TypeScript/pull/63193#issuecomment-3963099870 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/domResizeObserverExplicitArrayCallback.js | 9 +++++++++ .../domResizeObserverExplicitArrayCallback.symbols | 8 ++++++++ .../domResizeObserverExplicitArrayCallback.types | 9 +++++++++ .../compiler/domResizeObserverExplicitArrayCallback.ts | 5 +++++ 4 files changed, 31 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.js create mode 100644 tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.types create mode 100644 tsc/testdata/tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.js b/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.js new file mode 100644 index 0000000000000..b8067ff2130ad --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.js @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts] //// + +//// [domResizeObserverExplicitArrayCallback.ts] +new ResizeObserver((entries: ResizeObserverEntry[]) => {}); + + +//// [domResizeObserverExplicitArrayCallback.js] +"use strict"; +new ResizeObserver((entries) => { }); diff --git a/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.symbols b/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.symbols new file mode 100644 index 0000000000000..578821cef86e3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.symbols @@ -0,0 +1,8 @@ +//// [tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts] //// + +=== domResizeObserverExplicitArrayCallback.ts === +new ResizeObserver((entries: ResizeObserverEntry[]) => {}); +>ResizeObserver : Symbol(ResizeObserver, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>entries : Symbol(entries, Decl(domResizeObserverExplicitArrayCallback.ts, 0, 20)) +>ResizeObserverEntry : Symbol(ResizeObserverEntry, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.types b/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.types new file mode 100644 index 0000000000000..0ceb30a8c9a5b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domResizeObserverExplicitArrayCallback.types @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts] //// + +=== domResizeObserverExplicitArrayCallback.ts === +new ResizeObserver((entries: ResizeObserverEntry[]) => {}); +>new ResizeObserver((entries: ResizeObserverEntry[]) => {}) : ResizeObserver +>ResizeObserver : { new (callback: ResizeObserverCallback): ResizeObserver; prototype: ResizeObserver; } +>(entries: ResizeObserverEntry[]) => {} : (entries: ResizeObserverEntry[]) => void +>entries : ResizeObserverEntry[] + diff --git a/tsc/testdata/tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts b/tsc/testdata/tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts new file mode 100644 index 0000000000000..3002c4fbf1c6f --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domResizeObserverExplicitArrayCallback.ts @@ -0,0 +1,5 @@ +// @strict: true +// @target: es2015 +// @lib: es2015,dom + +new ResizeObserver((entries: ResizeObserverEntry[]) => {}); From 62da6f2c3e420f0d23321d14701d3eca3a18273c Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 08:25:50 -0700 Subject: [PATCH 092/116] Cover directory-reader array callbacks and readonly promises Capture contextual array length, an explicitly array-typed async callback, and a readonly-array Promise resolver passed directly to the genuine directory reader. Preserve the actual callback and Promise forms without SDK declarations, imports or casts. https://redirect.github.com/microsoft/TypeScript/pull/63193#issuecomment-3963099870 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../domDirectoryReaderArrayCallbacks.js | 23 ++++++++++++ .../domDirectoryReaderArrayCallbacks.symbols | 32 +++++++++++++++++ .../domDirectoryReaderArrayCallbacks.types | 36 +++++++++++++++++++ .../domDirectoryReaderArrayCallbacks.ts | 8 +++++ 4 files changed, 99 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.js create mode 100644 tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.types create mode 100644 tsc/testdata/tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts diff --git a/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.js b/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.js new file mode 100644 index 0000000000000..bfe680b32ecb8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts] //// + +//// [domDirectoryReaderArrayCallbacks.ts] +declare const reader: FileSystemDirectoryReader; +reader.readEntries(entries => entries.length); +reader.readEntries(async (entries: FileSystemEntry[]) => {}); +new Promise(resolve => reader.readEntries(resolve)); + + +//// [domDirectoryReaderArrayCallbacks.js] +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +reader.readEntries(entries => entries.length); +reader.readEntries((entries) => __awaiter(void 0, void 0, void 0, function* () { })); +new Promise(resolve => reader.readEntries(resolve)); diff --git a/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.symbols b/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.symbols new file mode 100644 index 0000000000000..b6647fa6f7a44 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts] //// + +=== domDirectoryReaderArrayCallbacks.ts === +declare const reader: FileSystemDirectoryReader; +>reader : Symbol(reader, Decl(domDirectoryReaderArrayCallbacks.ts, 0, 13)) +>FileSystemDirectoryReader : Symbol(FileSystemDirectoryReader, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +reader.readEntries(entries => entries.length); +>reader.readEntries : Symbol(FileSystemDirectoryReader.readEntries, Decl(lib.dom.d.ts, --, --)) +>reader : Symbol(reader, Decl(domDirectoryReaderArrayCallbacks.ts, 0, 13)) +>readEntries : Symbol(FileSystemDirectoryReader.readEntries, Decl(lib.dom.d.ts, --, --)) +>entries : Symbol(entries, Decl(domDirectoryReaderArrayCallbacks.ts, 1, 19)) +>entries.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(entries, Decl(domDirectoryReaderArrayCallbacks.ts, 1, 19)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) + +reader.readEntries(async (entries: FileSystemEntry[]) => {}); +>reader.readEntries : Symbol(FileSystemDirectoryReader.readEntries, Decl(lib.dom.d.ts, --, --)) +>reader : Symbol(reader, Decl(domDirectoryReaderArrayCallbacks.ts, 0, 13)) +>readEntries : Symbol(FileSystemDirectoryReader.readEntries, Decl(lib.dom.d.ts, --, --)) +>entries : Symbol(entries, Decl(domDirectoryReaderArrayCallbacks.ts, 2, 26)) +>FileSystemEntry : Symbol(FileSystemEntry, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +new Promise(resolve => reader.readEntries(resolve)); +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>FileSystemEntry : Symbol(FileSystemEntry, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>resolve : Symbol(resolve, Decl(domDirectoryReaderArrayCallbacks.ts, 3, 40)) +>reader.readEntries : Symbol(FileSystemDirectoryReader.readEntries, Decl(lib.dom.d.ts, --, --)) +>reader : Symbol(reader, Decl(domDirectoryReaderArrayCallbacks.ts, 0, 13)) +>readEntries : Symbol(FileSystemDirectoryReader.readEntries, Decl(lib.dom.d.ts, --, --)) +>resolve : Symbol(resolve, Decl(domDirectoryReaderArrayCallbacks.ts, 3, 40)) + diff --git a/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.types b/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.types new file mode 100644 index 0000000000000..c8a79cefb0191 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domDirectoryReaderArrayCallbacks.types @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts] //// + +=== domDirectoryReaderArrayCallbacks.ts === +declare const reader: FileSystemDirectoryReader; +>reader : FileSystemDirectoryReader + +reader.readEntries(entries => entries.length); +>reader.readEntries(entries => entries.length) : void +>reader.readEntries : (successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback) => void +>reader : FileSystemDirectoryReader +>readEntries : (successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback) => void +>entries => entries.length : (entries: FileSystemEntry[]) => number +>entries : FileSystemEntry[] +>entries.length : number +>entries : FileSystemEntry[] +>length : number + +reader.readEntries(async (entries: FileSystemEntry[]) => {}); +>reader.readEntries(async (entries: FileSystemEntry[]) => {}) : void +>reader.readEntries : (successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback) => void +>reader : FileSystemDirectoryReader +>readEntries : (successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback) => void +>async (entries: FileSystemEntry[]) => {} : (entries: FileSystemEntry[]) => Promise +>entries : FileSystemEntry[] + +new Promise(resolve => reader.readEntries(resolve)); +>new Promise(resolve => reader.readEntries(resolve)) : Promise +>Promise : PromiseConstructor +>resolve => reader.readEntries(resolve) : (resolve: (value: PromiseLike | readonly FileSystemEntry[]) => void) => void +>resolve : (value: PromiseLike | readonly FileSystemEntry[]) => void +>reader.readEntries(resolve) : void +>reader.readEntries : (successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback) => void +>reader : FileSystemDirectoryReader +>readEntries : (successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback) => void +>resolve : (value: PromiseLike | readonly FileSystemEntry[]) => void + diff --git a/tsc/testdata/tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts b/tsc/testdata/tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts new file mode 100644 index 0000000000000..73314c28a62bd --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domDirectoryReaderArrayCallbacks.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es2015 +// @lib: es2015,dom + +declare const reader: FileSystemDirectoryReader; +reader.readEntries(entries => entries.length); +reader.readEntries(async (entries: FileSystemEntry[]) => {}); +new Promise(resolve => reader.readEntries(resolve)); From 96844cb9c8c3503257442f8c4e2f0d0551ed1432 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 09:44:57 -0700 Subject: [PATCH 093/116] Test fetch compatibility after copying an overload signature Preserve compatibility when Parameters and ReturnType copy the last signature of an overloaded ambient fetch. The temporary Location widening rejected the copied callable even though its source type retained both overloads. https://redirect.github.com/microsoft/TypeScript/pull/64604#issuecomment-5959842795 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../fetchOverloadCallableCopy.symbols | 33 +++++++++++++++++++ .../compiler/fetchOverloadCallableCopy.types | 22 +++++++++++++ .../compiler/fetchOverloadCallableCopy.ts | 8 +++++ 3 files changed, 63 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.types create mode 100644 tsc/testdata/tests/cases/compiler/fetchOverloadCallableCopy.ts diff --git a/tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.symbols b/tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.symbols new file mode 100644 index 0000000000000..76988e0bdb5d8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.symbols @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/fetchOverloadCallableCopy.ts] //// + +=== fetchOverloadCallableCopy.ts === +declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise; +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --), Decl(fetchOverloadCallableCopy.ts, 0, 0)) +>input : Symbol(input, Decl(fetchOverloadCallableCopy.ts, 0, 23)) +>RequestInfo : Symbol(RequestInfo, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>init : Symbol(init, Decl(fetchOverloadCallableCopy.ts, 0, 48)) +>RequestInit : Symbol(RequestInit, Decl(lib.dom.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Response : Symbol(Response, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +type CallableCopy unknown> = (...args: Parameters) => ReturnType; +>CallableCopy : Symbol(CallableCopy, Decl(fetchOverloadCallableCopy.ts, 0, 88)) +>T : Symbol(T, Decl(fetchOverloadCallableCopy.ts, 1, 18)) +>args : Symbol(args, Decl(fetchOverloadCallableCopy.ts, 1, 29)) +>args : Symbol(args, Decl(fetchOverloadCallableCopy.ts, 1, 62)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(fetchOverloadCallableCopy.ts, 1, 18)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(fetchOverloadCallableCopy.ts, 1, 18)) + +declare const copiedFetch: CallableCopy; +>copiedFetch : Symbol(copiedFetch, Decl(fetchOverloadCallableCopy.ts, 2, 13)) +>CallableCopy : Symbol(CallableCopy, Decl(fetchOverloadCallableCopy.ts, 0, 88)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --), Decl(fetchOverloadCallableCopy.ts, 0, 0)) + +const replacementFetch: typeof fetch = copiedFetch; +>replacementFetch : Symbol(replacementFetch, Decl(fetchOverloadCallableCopy.ts, 3, 5)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --), Decl(fetchOverloadCallableCopy.ts, 0, 0)) +>copiedFetch : Symbol(copiedFetch, Decl(fetchOverloadCallableCopy.ts, 2, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.types b/tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.types new file mode 100644 index 0000000000000..faf620e772fd8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/fetchOverloadCallableCopy.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/fetchOverloadCallableCopy.ts] //// + +=== fetchOverloadCallableCopy.ts === +declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise; +>fetch : { (input: RequestInfo | URL, init?: RequestInit): Promise; (input: RequestInfo | URL, init?: RequestInit): Promise; } +>input : URL | RequestInfo +>init : RequestInit | undefined + +type CallableCopy unknown> = (...args: Parameters) => ReturnType; +>CallableCopy : CallableCopy +>args : never[] +>args : Parameters + +declare const copiedFetch: CallableCopy; +>copiedFetch : CallableCopy<{ (input: RequestInfo | URL, init?: RequestInit): Promise; (input: RequestInfo | URL, init?: RequestInit): Promise; }> +>fetch : { (input: RequestInfo | URL, init?: RequestInit): Promise; (input: RequestInfo | URL, init?: RequestInit): Promise; } + +const replacementFetch: typeof fetch = copiedFetch; +>replacementFetch : { (input: RequestInfo | URL, init?: RequestInit): Promise; (input: RequestInfo | URL, init?: RequestInit): Promise; } +>fetch : { (input: RequestInfo | URL, init?: RequestInit): Promise; (input: RequestInfo | URL, init?: RequestInit): Promise; } +>copiedFetch : CallableCopy<{ (input: RequestInfo | URL, init?: RequestInit): Promise; (input: RequestInfo | URL, init?: RequestInit): Promise; }> + diff --git a/tsc/testdata/tests/cases/compiler/fetchOverloadCallableCopy.ts b/tsc/testdata/tests/cases/compiler/fetchOverloadCallableCopy.ts new file mode 100644 index 0000000000000..68258e8ce4aa0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/fetchOverloadCallableCopy.ts @@ -0,0 +1,8 @@ +// @strict: true +// @lib: es2015,dom +// @noEmit: true + +declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise; +type CallableCopy unknown> = (...args: Parameters) => ReturnType; +declare const copiedFetch: CallableCopy; +const replacementFetch: typeof fetch = copiedFetch; From f4be4f89b5e84b94eeec0ef26143566113fa142f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 09:45:09 -0700 Subject: [PATCH 094/116] Test contextual fetch input narrowing to Request.url After excluding strings and URLs from a contextual fetch input, the remaining Request has a readable url. The reverted Location widening introduced a missing-property error at that read. https://redirect.github.com/microsoft/TypeScript/pull/64604#issuecomment-5959842795 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../fetchContextualRequestUrl.symbols | 27 ++++++++++++++ .../compiler/fetchContextualRequestUrl.types | 35 +++++++++++++++++++ .../compiler/fetchContextualRequestUrl.ts | 8 +++++ 3 files changed, 70 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.types create mode 100644 tsc/testdata/tests/cases/compiler/fetchContextualRequestUrl.ts diff --git a/tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.symbols b/tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.symbols new file mode 100644 index 0000000000000..3b3293fa12bdb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/fetchContextualRequestUrl.ts] //// + +=== fetchContextualRequestUrl.ts === +const fetchUsingRequestUrl: typeof fetch = async input => { +>fetchUsingRequestUrl : Symbol(fetchUsingRequestUrl, Decl(fetchContextualRequestUrl.ts, 0, 5)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>input : Symbol(input, Decl(fetchContextualRequestUrl.ts, 0, 48)) + + const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; +>url : Symbol(url, Decl(fetchContextualRequestUrl.ts, 1, 9)) +>input : Symbol(input, Decl(fetchContextualRequestUrl.ts, 0, 48)) +>input : Symbol(input, Decl(fetchContextualRequestUrl.ts, 0, 48)) +>input : Symbol(input, Decl(fetchContextualRequestUrl.ts, 0, 48)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>input.href : Symbol(URL.href, Decl(lib.dom.d.ts, --, --)) +>input : Symbol(input, Decl(fetchContextualRequestUrl.ts, 0, 48)) +>href : Symbol(URL.href, Decl(lib.dom.d.ts, --, --)) +>input.url : Symbol(Request.url, Decl(lib.dom.d.ts, --, --)) +>input : Symbol(input, Decl(fetchContextualRequestUrl.ts, 0, 48)) +>url : Symbol(Request.url, Decl(lib.dom.d.ts, --, --)) + + return new Response(url); +>Response : Symbol(Response, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>url : Symbol(url, Decl(fetchContextualRequestUrl.ts, 1, 9)) + +}; + diff --git a/tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.types b/tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.types new file mode 100644 index 0000000000000..f22b259a12191 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/fetchContextualRequestUrl.types @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/fetchContextualRequestUrl.ts] //// + +=== fetchContextualRequestUrl.ts === +const fetchUsingRequestUrl: typeof fetch = async input => { +>fetchUsingRequestUrl : (input: RequestInfo | URL, init?: RequestInit) => Promise +>fetch : (input: RequestInfo | URL, init?: RequestInit) => Promise +>async input => { const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; return new Response(url);} : (input: URL | RequestInfo) => Promise +>input : URL | RequestInfo + + const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; +>url : string +>typeof input === "string" ? input : input instanceof URL ? input.href : input.url : string +>typeof input === "string" : boolean +>typeof input : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>input : URL | RequestInfo +>"string" : "string" +>input : string +>input instanceof URL ? input.href : input.url : string +>input instanceof URL : boolean +>input : Request | URL +>URL : { new (url: string | URL, base?: string | URL): URL; prototype: URL; canParse(url: string | URL, base?: string | URL): boolean; createObjectURL(obj: Blob | MediaSource): string; parse(url: string | URL, base?: string | URL): URL | null; revokeObjectURL(url: string): void; } +>input.href : string +>input : URL +>href : string +>input.url : string +>input : Request +>url : string + + return new Response(url); +>new Response(url) : Response +>Response : { new (body?: BodyInit | null, init?: ResponseInit): Response; prototype: Response; error(): Response; json(data: any, init?: ResponseInit): Response; redirect(url: string | URL, status?: number): Response; } +>url : string + +}; + diff --git a/tsc/testdata/tests/cases/compiler/fetchContextualRequestUrl.ts b/tsc/testdata/tests/cases/compiler/fetchContextualRequestUrl.ts new file mode 100644 index 0000000000000..1bdd5e3937024 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/fetchContextualRequestUrl.ts @@ -0,0 +1,8 @@ +// @strict: true +// @lib: es2015,dom +// @noEmit: true + +const fetchUsingRequestUrl: typeof fetch = async input => { + const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; + return new Response(url); +}; From 800b05e6ced79937bf589911b87cc07c52bed3f8 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 10:32:31 -0700 Subject: [PATCH 095/116] Test generic return context for optional class fields Preserve declared field context for a defaulted constrained generic call under an optional-field guard, including the subsequent definite property read. Authentic PR60395 report-era snapshots change this minimal case from clean to TS2741 and TS2532; the later final pair and current native compiler are clean. Explicit type arguments independently remove the experimental errors. Seven closest active fixtures preserve their diagnostics and observed types across both original pairs. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60395#issuecomment-2455740314 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...lGenericReturnToOptionalClassField.symbols | 36 ++++++++++++++++++ ...ualGenericReturnToOptionalClassField.types | 37 +++++++++++++++++++ ...extualGenericReturnToOptionalClassField.ts | 13 +++++++ 3 files changed, 86 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.types create mode 100644 tsc/testdata/tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts diff --git a/tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.symbols b/tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.symbols new file mode 100644 index 0000000000000..215f6ad388cca --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.symbols @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts] //// + +=== contextualGenericReturnToOptionalClassField.ts === +declare function lookup(): T; +>lookup : Symbol(lookup, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 0)) +>T : Symbol(T, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 24)) +>T : Symbol(T, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 24)) + +class Container { +>Container : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56)) + + item?: { label: string }; +>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>label : Symbol(label, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 12)) + + getLabel() { +>getLabel : Symbol(Container.getLabel, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 29)) + + if (!this.item) this.item = lookup(); +>this.item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>this : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56)) +>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>this.item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>this : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56)) +>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>lookup : Symbol(lookup, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 0)) + + return this.item.label; +>this.item.label : Symbol(label, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 12)) +>this.item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>this : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56)) +>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17)) +>label : Symbol(label, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 12)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.types b/tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.types new file mode 100644 index 0000000000000..9620d0af078e2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualGenericReturnToOptionalClassField.types @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts] //// + +=== contextualGenericReturnToOptionalClassField.ts === +declare function lookup(): T; +>lookup : () => T + +class Container { +>Container : Container + + item?: { label: string }; +>item : { label: string; } | undefined +>label : string + + getLabel() { +>getLabel : () => string + + if (!this.item) this.item = lookup(); +>!this.item : boolean +>this.item : { label: string; } | undefined +>this : this +>item : { label: string; } | undefined +>this.item = lookup() : { label: string; } +>this.item : { label: string; } | undefined +>this : this +>item : { label: string; } | undefined +>lookup() : { label: string; } +>lookup : () => T + + return this.item.label; +>this.item.label : string +>this.item : { label: string; } +>this : this +>item : { label: string; } +>label : string + } +} + diff --git a/tsc/testdata/tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts b/tsc/testdata/tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts new file mode 100644 index 0000000000000..ceb8cc379018d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts @@ -0,0 +1,13 @@ +// @strict: true +// @target: es2015 +// @lib: es5 +// @noEmit: true + +declare function lookup(): T; +class Container { + item?: { label: string }; + getLabel() { + if (!this.item) this.item = lookup(); + return this.item.label; + } +} From b21ed7157acb358990cf6a879d84af48c63c3c76 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 10:32:48 -0700 Subject: [PATCH 096/116] Test contextual factory results assigned to optional class fields Preserve a containing class type parameter when a generic constructor factory derives its result constraint through InstanceType and the result is assigned to an optional field. This separately reduces the authentic VS Code createInstance contracts, rather than treating them as defaulted DOM lookups. Original report-era phases produce sole TS2322; both original final phases and native stay clean. Explicit factory result arguments and an independently typed local both remove the experimental error. Origin: https://redirect.github.com/microsoft/TypeScript/pull/60395#issuecomment-2455740314 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...lFactoryReturnToOptionalClassField.symbols | 37 +++++++++++++++++++ ...ualFactoryReturnToOptionalClassField.types | 28 ++++++++++++++ ...extualFactoryReturnToOptionalClassField.ts | 11 ++++++ 3 files changed, 76 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.types create mode 100644 tsc/testdata/tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts diff --git a/tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.symbols b/tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.symbols new file mode 100644 index 0000000000000..66cc491275490 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts] //// + +=== contextualFactoryReturnToOptionalClassField.ts === +class Reply { value!: T; } +>Reply : Symbol(Reply, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 0)) +>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 12)) +>value : Symbol(Reply.value, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 40)) +>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 12)) + +declare function create unknown, R extends InstanceType>(ctor: Ctor): R; +>create : Symbol(create, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 53)) +>Ctor : Symbol(Ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 24)) +>R : Symbol(R, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 55)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>Ctor : Symbol(Ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 24)) +>ctor : Symbol(ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 86)) +>Ctor : Symbol(Ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 24)) +>R : Symbol(R, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 55)) + +class Container { +>Container : Symbol(Container, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 101)) +>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 16)) + + item?: Reply; +>item : Symbol(Container.item, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 44)) +>Reply : Symbol(Reply, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 0)) +>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 16)) + + initialize() { this.item = create(Reply); } +>initialize : Symbol(Container.initialize, Decl(contextualFactoryReturnToOptionalClassField.ts, 3, 20)) +>this.item : Symbol(Container.item, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 44)) +>this : Symbol(Container, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 101)) +>item : Symbol(Container.item, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 44)) +>create : Symbol(create, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 53)) +>Reply : Symbol(Reply, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 0)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.types b/tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.types new file mode 100644 index 0000000000000..d380cf0573ee0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualFactoryReturnToOptionalClassField.types @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts] //// + +=== contextualFactoryReturnToOptionalClassField.ts === +class Reply { value!: T; } +>Reply : Reply +>value : T + +declare function create unknown, R extends InstanceType>(ctor: Ctor): R; +>create : unknown, R extends InstanceType>(ctor: Ctor) => R +>ctor : Ctor + +class Container { +>Container : Container + + item?: Reply; +>item : Reply | undefined + + initialize() { this.item = create(Reply); } +>initialize : () => void +>this.item = create(Reply) : Reply +>this.item : Reply | undefined +>this : this +>item : Reply | undefined +>create(Reply) : Reply +>create : unknown, R extends InstanceType>(ctor: Ctor) => R +>Reply : typeof Reply +} + diff --git a/tsc/testdata/tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts b/tsc/testdata/tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts new file mode 100644 index 0000000000000..3a7a53b801ffb --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts @@ -0,0 +1,11 @@ +// @strict: true +// @target: es2015 +// @lib: es5 +// @noEmit: true + +class Reply { value!: T; } +declare function create unknown, R extends InstanceType>(ctor: Ctor): R; +class Container { + item?: Reply; + initialize() { this.item = create(Reply); } +} From 4a84c00473456e1c73bda642dfdd72ac2bec9e4f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 10:33:02 -0700 Subject: [PATCH 097/116] Test module keyword on an instantiated runtime namespace Cover a real ValueModule with an exported value and a value use, not only the existing empty or ambient namespace forms. The initial PR61450 prevalence experiment rejects this instantiated form while all three closest active fixtures retain no TS1294; its later predicate also rejects ambient forms. Original before and the independent namespace-token control remain clean. Current TS1540 is intentional compatibility characterization, not the historical reused ESO message or a claim that erasableSyntaxOnly was enabled. Origins: https://redirect.github.com/microsoft/TypeScript/pull/61450#issuecomment-2738465364 https://redirect.github.com/microsoft/TypeScript/pull/61450#issuecomment-2744477736 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../moduleKeywordInstantiatedNamespace.errors.txt | 11 +++++++++++ .../moduleKeywordInstantiatedNamespace.symbols | 14 ++++++++++++++ .../moduleKeywordInstantiatedNamespace.types | 15 +++++++++++++++ .../moduleKeywordInstantiatedNamespace.ts | 7 +++++++ 4 files changed, 47 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.types create mode 100644 tsc/testdata/tests/cases/compiler/moduleKeywordInstantiatedNamespace.ts diff --git a/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.errors.txt b/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.errors.txt new file mode 100644 index 0000000000000..257e5f5fbbbf2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.errors.txt @@ -0,0 +1,11 @@ +moduleKeywordInstantiatedNamespace.ts(1,8): error TS1540: A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead. + + +==== moduleKeywordInstantiatedNamespace.ts (1 errors) ==== + module Runtime { + ~~~~~~~ +!!! error TS1540: A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead. + export const value = 0; + } + Runtime.value; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.symbols b/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.symbols new file mode 100644 index 0000000000000..b6a8427268b5f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.symbols @@ -0,0 +1,14 @@ +//// [tests/cases/compiler/moduleKeywordInstantiatedNamespace.ts] //// + +=== moduleKeywordInstantiatedNamespace.ts === +module Runtime { +>Runtime : Symbol(Runtime, Decl(moduleKeywordInstantiatedNamespace.ts, 0, 0)) + + export const value = 0; +>value : Symbol(value, Decl(moduleKeywordInstantiatedNamespace.ts, 1, 16)) +} +Runtime.value; +>Runtime.value : Symbol(Runtime.value, Decl(moduleKeywordInstantiatedNamespace.ts, 1, 16)) +>Runtime : Symbol(Runtime, Decl(moduleKeywordInstantiatedNamespace.ts, 0, 0)) +>value : Symbol(Runtime.value, Decl(moduleKeywordInstantiatedNamespace.ts, 1, 16)) + diff --git a/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.types b/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.types new file mode 100644 index 0000000000000..216d4b86ccda6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/moduleKeywordInstantiatedNamespace.types @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/moduleKeywordInstantiatedNamespace.ts] //// + +=== moduleKeywordInstantiatedNamespace.ts === +module Runtime { +>Runtime : typeof Runtime + + export const value = 0; +>value : 0 +>0 : 0 +} +Runtime.value; +>Runtime.value : 0 +>Runtime : typeof Runtime +>value : 0 + diff --git a/tsc/testdata/tests/cases/compiler/moduleKeywordInstantiatedNamespace.ts b/tsc/testdata/tests/cases/compiler/moduleKeywordInstantiatedNamespace.ts new file mode 100644 index 0000000000000..a9806e7addf59 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/moduleKeywordInstantiatedNamespace.ts @@ -0,0 +1,7 @@ +// @target: es2015 +// @noEmit: true + +module Runtime { + export const value = 0; +} +Runtime.value; From c83c7191f32d0d84c8a11d5f40bd36a3b7830b78 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 11:20:22 -0700 Subject: [PATCH 098/116] Cover conditional inference from function and value unions Reduce the six TanStack Query inference regressions to a self-contained recursive conditional type and one function argument. Authentic report-era compilers infer a function/value union instead of the object result; explicit generic controls isolate inference. Keep the current clean behavior and inferred types under a native compiler baseline. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62093#issuecomment-3098762445 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../conditionalFunctionUnionInference.symbols | 35 +++++++++++++++++++ .../conditionalFunctionUnionInference.types | 27 ++++++++++++++ .../conditionalFunctionUnionInference.ts | 11 ++++++ 3 files changed, 73 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.types create mode 100644 tsc/testdata/tests/cases/compiler/conditionalFunctionUnionInference.ts diff --git a/tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.symbols b/tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.symbols new file mode 100644 index 0000000000000..62dce6dbeabf9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.symbols @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/conditionalFunctionUnionInference.ts] //// + +=== conditionalFunctionUnionInference.ts === +type DeepValue = T extends () => unknown ? T : +>DeepValue : Symbol(DeepValue, Decl(conditionalFunctionUnionInference.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15)) + + { [K in keyof T]: DeepValue }; +>K : Symbol(K, Decl(conditionalFunctionUnionInference.ts, 1, 7)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15)) +>DeepValue : Symbol(DeepValue, Decl(conditionalFunctionUnionInference.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15)) +>K : Symbol(K, Decl(conditionalFunctionUnionInference.ts, 1, 7)) + +declare function createValue(initialValue: DeepValue T)>): T; +>createValue : Symbol(createValue, Decl(conditionalFunctionUnionInference.ts, 1, 40)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29)) +>initialValue : Symbol(initialValue, Decl(conditionalFunctionUnionInference.ts, 3, 32)) +>DeepValue : Symbol(DeepValue, Decl(conditionalFunctionUnionInference.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29)) +>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29)) + +const value = createValue(() => ({ ready: true })); +>value : Symbol(value, Decl(conditionalFunctionUnionInference.ts, 5, 5)) +>createValue : Symbol(createValue, Decl(conditionalFunctionUnionInference.ts, 1, 40)) +>ready : Symbol(ready, Decl(conditionalFunctionUnionInference.ts, 5, 34)) + +value.ready; +>value.ready : Symbol(ready, Decl(conditionalFunctionUnionInference.ts, 5, 34)) +>value : Symbol(value, Decl(conditionalFunctionUnionInference.ts, 5, 5)) +>ready : Symbol(ready, Decl(conditionalFunctionUnionInference.ts, 5, 34)) + diff --git a/tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.types b/tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.types new file mode 100644 index 0000000000000..def30ad1a676b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalFunctionUnionInference.types @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/conditionalFunctionUnionInference.ts] //// + +=== conditionalFunctionUnionInference.ts === +type DeepValue = T extends () => unknown ? T : +>DeepValue : DeepValue + + { [K in keyof T]: DeepValue }; + +declare function createValue(initialValue: DeepValue T)>): T; +>createValue : (initialValue: DeepValue T)>) => T +>initialValue : (() => T) | DeepValue + +const value = createValue(() => ({ ready: true })); +>value : { ready: boolean; } +>createValue(() => ({ ready: true })) : { ready: boolean; } +>createValue : (initialValue: DeepValue T)>) => T +>() => ({ ready: true }) : () => { ready: boolean; } +>({ ready: true }) : { ready: true; } +>{ ready: true } : { ready: true; } +>ready : true +>true : true + +value.ready; +>value.ready : boolean +>value : { ready: boolean; } +>ready : boolean + diff --git a/tsc/testdata/tests/cases/compiler/conditionalFunctionUnionInference.ts b/tsc/testdata/tests/cases/compiler/conditionalFunctionUnionInference.ts new file mode 100644 index 0000000000000..47a9277a5c0c9 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/conditionalFunctionUnionInference.ts @@ -0,0 +1,11 @@ +// @strict: true +// @target: es2015 +// @noEmit: true + +type DeepValue = T extends () => unknown ? T : + { [K in keyof T]: DeepValue }; + +declare function createValue(initialValue: DeepValue T)>): T; + +const value = createValue(() => ({ ready: true })); +value.ready; From d7b77156aaa6d81743b6b3e46756669071497908 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 12:19:54 -0700 Subject: [PATCH 099/116] Cover asserted assignment to readonly parameter properties Preserve the current-compatible asserted property-access form, separate from the existing asserted class-binding and mutable private-field tests. Both abandoned experimental heads reject the readonly constructor parameter property; both authentic parents and native controls accept it. The unknown assertion is independently measured equivalent to the original any assertion. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62128#issuecomment-3120340890 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...eadonlyParameterPropertyAssignment.symbols | 19 ++++++++++++++++ ...dReadonlyParameterPropertyAssignment.types | 22 +++++++++++++++++++ ...rtedReadonlyParameterPropertyAssignment.ts | 10 +++++++++ 3 files changed, 51 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.types create mode 100644 tsc/testdata/tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts diff --git a/tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.symbols b/tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.symbols new file mode 100644 index 0000000000000..cd414f19466f8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts] //// + +=== assertedReadonlyParameterPropertyAssignment.ts === +class ReadonlyState { +>ReadonlyState : Symbol(ReadonlyState, Decl(assertedReadonlyParameterPropertyAssignment.ts, 0, 0)) + + constructor(readonly value: object) {} +>value : Symbol(ReadonlyState.value, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 16)) + + clear() { +>clear : Symbol(ReadonlyState.clear, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 42)) + + (this.value as unknown) = null; +>this.value : Symbol(ReadonlyState.value, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 16)) +>this : Symbol(ReadonlyState, Decl(assertedReadonlyParameterPropertyAssignment.ts, 0, 0)) +>value : Symbol(ReadonlyState.value, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 16)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.types b/tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.types new file mode 100644 index 0000000000000..dbd17a6389a60 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/assertedReadonlyParameterPropertyAssignment.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts] //// + +=== assertedReadonlyParameterPropertyAssignment.ts === +class ReadonlyState { +>ReadonlyState : ReadonlyState + + constructor(readonly value: object) {} +>value : object + + clear() { +>clear : () => void + + (this.value as unknown) = null; +>(this.value as unknown) = null : null +>(this.value as unknown) : unknown +>this.value as unknown : unknown +>this.value : object +>this : this +>value : object + } +} + diff --git a/tsc/testdata/tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts b/tsc/testdata/tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts new file mode 100644 index 0000000000000..3580f347ae678 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts @@ -0,0 +1,10 @@ +// @strict: true +// @target: es2015 +// @noEmit: true + +class ReadonlyState { + constructor(readonly value: object) {} + clear() { + (this.value as unknown) = null; + } +} From b9009d730a7d4c4adceb66908c7e3d48335635be Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 15 Oct 2026 12:20:36 -0700 Subject: [PATCH 100/116] Cover asserted writes through generic Partial indexes Preserve the current-compatible asserted element-access form for a string key on Partial. Both abandoned experimental heads activate Writing/NoIndexSignatures and reject the write, while both authentic parents and native controls accept it. The two original MUI source sites have the same form; this is independent of class-symbol and readonly-parameter-property checks. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62128#issuecomment-3120340890 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...rtedGenericPartialIndexedAssignment.symbols | 17 +++++++++++++++++ ...sertedGenericPartialIndexedAssignment.types | 18 ++++++++++++++++++ .../assertedGenericPartialIndexedAssignment.ts | 7 +++++++ 3 files changed, 42 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.types create mode 100644 tsc/testdata/tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts diff --git a/tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.symbols b/tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.symbols new file mode 100644 index 0000000000000..5cb9272d772b8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts] //// + +=== assertedGenericPartialIndexedAssignment.ts === +function write>(values: Partial, key: string) { +>write : Symbol(write, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 0)) +>T : Symbol(T, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 15)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>values : Symbol(values, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 50)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 15)) +>key : Symbol(key, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 69)) + + (values[key] as unknown) = 0; +>values : Symbol(values, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 50)) +>key : Symbol(key, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 69)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.types b/tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.types new file mode 100644 index 0000000000000..3b7fa53bf9f44 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/assertedGenericPartialIndexedAssignment.types @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts] //// + +=== assertedGenericPartialIndexedAssignment.ts === +function write>(values: Partial, key: string) { +>write : >(values: Partial, key: string) => void +>values : Partial +>key : string + + (values[key] as unknown) = 0; +>(values[key] as unknown) = 0 : 0 +>(values[key] as unknown) : unknown +>values[key] as unknown : unknown +>values[key] : T[string] | undefined +>values : Partial +>key : string +>0 : 0 +} + diff --git a/tsc/testdata/tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts b/tsc/testdata/tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts new file mode 100644 index 0000000000000..983e084df3089 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts @@ -0,0 +1,7 @@ +// @strict: true +// @target: es2015 +// @noEmit: true + +function write>(values: Partial, key: string) { + (values[key] as unknown) = 0; +} From 5e107b123b70241e075d9990551e303caea5b3c3 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 00:18:23 -0700 Subject: [PATCH 101/116] Cover valid NodeNext conditional exports fallback Add a self-contained ESM import with compatible NodeNext module options and a later types condition after an untyped .mjs export. The trace preserves typed fallback resolution without relying on an incompatible module error. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62310#issuecomment-3251203808 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...portsResolutionFallbackNodeNext.trace.json | 23 ++++++++++++++ ...tionalExportsResolutionFallbackNodeNext.ts | 31 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tsc/testdata/baselines/reference/conformance/conditionalExportsResolutionFallbackNodeNext.trace.json create mode 100644 tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsResolutionFallbackNodeNext.ts diff --git a/tsc/testdata/baselines/reference/conformance/conditionalExportsResolutionFallbackNodeNext.trace.json b/tsc/testdata/baselines/reference/conformance/conditionalExportsResolutionFallbackNodeNext.trace.json new file mode 100644 index 0000000000000..e49e2b61f6cab --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/conditionalExportsResolutionFallbackNodeNext.trace.json @@ -0,0 +1,23 @@ +======== Resolving module 'dep' from '/index.mts'. ======== +Explicitly specified module resolution kind: 'NodeNext'. +Resolving in ESM mode with conditions 'import', 'types', 'node'. +File '/package.json' does not exist. +Loading module 'dep' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON. +Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration. +Found 'package.json' at '/node_modules/dep/package.json'. +Entering conditional exports. +Matched 'exports' condition 'import'. +Using 'exports' subpath '.' with target './index.mjs'. +File name '/node_modules/dep/index.mjs' has a '.mjs' extension - stripping it. +File '/node_modules/dep/index.mts' does not exist. +File '/node_modules/dep/index.d.mts' does not exist. +Failed to resolve under condition 'import'. +Saw non-matching condition 'require'. +Matched 'exports' condition 'types'. +Using 'exports' subpath '.' with target './index.d.ts'. +File '/node_modules/dep/index.d.ts' exists - use it as a name resolution result. +'package.json' does not have a 'peerDependencies' field. +Resolved under condition 'types'. +Exiting conditional exports. +Resolving real path for '/node_modules/dep/index.d.ts', result '/node_modules/dep/index.d.ts'. +======== Module name 'dep' was successfully resolved to '/node_modules/dep/index.d.ts' with Package ID 'dep/index.d.ts@1.0.0'. ======== diff --git a/tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsResolutionFallbackNodeNext.ts b/tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsResolutionFallbackNodeNext.ts new file mode 100644 index 0000000000000..6b904b42933df --- /dev/null +++ b/tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsResolutionFallbackNodeNext.ts @@ -0,0 +1,31 @@ +// @target: es2022 +// @module: nodenext +// @moduleResolution: nodenext +// @strict: true +// @traceResolution: true +// @noTypesAndSymbols: true +// @noEmit: true +// @noImplicitReferences: true + +// @Filename: /node_modules/dep/package.json +{ + "name": "dep", + "version": "1.0.0", + "types": "./index.d.ts", + "exports": { + ".": { + "import": "./index.mjs", + "require": "./index.js", + "types": "./index.d.ts" + } + } +} + +// @Filename: /node_modules/dep/index.d.ts +export {}; + +// @Filename: /node_modules/dep/index.mjs +export {}; + +// @Filename: /index.mts +import {} from "dep"; From 4811a5e5d2186c5ed8b723ce99e560e295fb4eb9 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 04:02:58 -0700 Subject: [PATCH 102/116] Cover CommonJS conditional exports require-to-default fallback Add a self-contained CommonJS import with unspecified module resolution. The trace preserves implicit Bundler resolution past a require .cjs target without a .d.cts sidecar to the default .js target's .d.ts declaration. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62310#issuecomment-3251203783 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ionalExportsRequireDefaultFallback.symbols | 10 ++++++++ ...alExportsRequireDefaultFallback.trace.json | 24 +++++++++++++++++++ ...itionalExportsRequireDefaultFallback.types | 10 ++++++++ ...onditionalExportsRequireDefaultFallback.ts | 24 +++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.symbols create mode 100644 tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.trace.json create mode 100644 tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.types create mode 100644 tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsRequireDefaultFallback.ts diff --git a/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.symbols b/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.symbols new file mode 100644 index 0000000000000..0696f4cdbf951 --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/moduleResolution/conditionalExportsRequireDefaultFallback.ts] //// + +=== /main.ts === +import { value } from "provider"; +>value : Symbol(value, Decl(main.ts, 0, 8)) + +=== /node_modules/provider/index.d.ts === +export const value: number; +>value : Symbol(value, Decl(index.d.ts, 0, 12)) + diff --git a/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.trace.json b/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.trace.json new file mode 100644 index 0000000000000..04e445855d68e --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.trace.json @@ -0,0 +1,24 @@ +======== Resolving module 'provider' from '/main.ts'. ======== +Module resolution kind is not specified, using 'Bundler'. +Resolving in CJS mode with conditions 'require', 'types'. +File '/package.json' does not exist. +Loading module 'provider' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON. +Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration. +Found 'package.json' at '/node_modules/provider/package.json'. +Entering conditional exports. +Matched 'exports' condition 'require'. +Using 'exports' subpath '.' with target './index.cjs'. +File name '/node_modules/provider/index.cjs' has a '.cjs' extension - stripping it. +File '/node_modules/provider/index.cts' does not exist. +File '/node_modules/provider/index.d.cts' does not exist. +Failed to resolve under condition 'require'. +Matched 'exports' condition 'default'. +Using 'exports' subpath '.' with target './index.js'. +File name '/node_modules/provider/index.js' has a '.js' extension - stripping it. +File '/node_modules/provider/index.ts' does not exist. +File '/node_modules/provider/index.tsx' does not exist. +File '/node_modules/provider/index.d.ts' exists - use it as a name resolution result. +Resolved under condition 'default'. +Exiting conditional exports. +Resolving real path for '/node_modules/provider/index.d.ts', result '/node_modules/provider/index.d.ts'. +======== Module name 'provider' was successfully resolved to '/node_modules/provider/index.d.ts'. ======== diff --git a/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.types b/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.types new file mode 100644 index 0000000000000..6d3301f2fb030 --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/conditionalExportsRequireDefaultFallback.types @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/moduleResolution/conditionalExportsRequireDefaultFallback.ts] //// + +=== /main.ts === +import { value } from "provider"; +>value : number + +=== /node_modules/provider/index.d.ts === +export const value: number; +>value : number + diff --git a/tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsRequireDefaultFallback.ts b/tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsRequireDefaultFallback.ts new file mode 100644 index 0000000000000..c46205e93ecf7 --- /dev/null +++ b/tsc/testdata/tests/cases/conformance/moduleResolution/conditionalExportsRequireDefaultFallback.ts @@ -0,0 +1,24 @@ +// @module: commonjs +// @strict: true +// @noEmit: true +// @traceResolution: true +// @noImplicitReferences: true + +// @filename: /node_modules/provider/package.json +{ + "exports": { + ".": { + "require": "./index.cjs", + "default": "./index.js" + } + } +} + +// @filename: /node_modules/provider/index.cjs +exports.value = 0; + +// @filename: /node_modules/provider/index.d.ts +export const value: number; + +// @filename: /main.ts +import { value } from "provider"; From 894de51178cd762f425a30b9a5f7355291624d67 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 09:37:57 -0700 Subject: [PATCH 103/116] Cover implicit rootDir with inherited include and outDir Exercise real child-config parsing with omitted noncomposite rootDir and an inherited include selecting a source outside the child directory. Preserve both current TS5011 and TS6059 diagnostics. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62418#issuecomment-3268362677 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../defaultRootDirInheritedInclude.errors.txt | 28 +++++++++++++++++++ .../defaultRootDirInheritedInclude.js | 16 +++++++++++ .../defaultRootDirInheritedInclude.symbols | 6 ++++ .../defaultRootDirInheritedInclude.types | 7 +++++ .../defaultRootDirInheritedInclude.ts | 17 +++++++++++ 5 files changed, 74 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.js create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultRootDirInheritedInclude.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.errors.txt b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.errors.txt new file mode 100644 index 0000000000000..bc1f6edc203d9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.errors.txt @@ -0,0 +1,28 @@ +error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout. + Visit https://aka.ms/ts6 for migration information. +error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files. + The file is in the program because: + Matched by include pattern '../src' in '/project/example/tsconfig.json' + + +!!! error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout. +!!! error TS5011: Visit https://aka.ms/ts6 for migration information. +!!! error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files. +!!! error TS6059: The file is in the program because: +!!! error TS6059: Matched by include pattern '../src' in '/project/example/tsconfig.json' +==== /project/example/tsconfig.json (0 errors) ==== + { + "extends": "../tsconfig.json" + } + +==== /project/src/index.ts (0 errors) ==== + export const value = 0; + +==== /project/tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "outDir": "lib" + }, + "include": ["src"] + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.js b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.js new file mode 100644 index 0000000000000..fdebc4a1da7cb --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/defaultRootDirInheritedInclude.ts] //// + +//// [tsconfig.json] +{ + "compilerOptions": { + "outDir": "lib" + }, + "include": ["src"] +} + +//// [index.ts] +export const value = 0; + + +//// [index.js] +export const value = 0; diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.symbols b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.symbols new file mode 100644 index 0000000000000..3785ff1e67011 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.symbols @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultRootDirInheritedInclude.ts] //// + +=== /project/src/index.ts === +export const value = 0; +>value : Symbol(value, Decl(index.ts, 0, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.types b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.types new file mode 100644 index 0000000000000..75f03aa99ea74 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirInheritedInclude.types @@ -0,0 +1,7 @@ +//// [tests/cases/compiler/defaultRootDirInheritedInclude.ts] //// + +=== /project/src/index.ts === +export const value = 0; +>value : 0 +>0 : 0 + diff --git a/tsc/testdata/tests/cases/compiler/defaultRootDirInheritedInclude.ts b/tsc/testdata/tests/cases/compiler/defaultRootDirInheritedInclude.ts new file mode 100644 index 0000000000000..2958320765709 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultRootDirInheritedInclude.ts @@ -0,0 +1,17 @@ +// @currentDirectory: /project + +// @filename: /project/example/tsconfig.json +{ + "extends": "../tsconfig.json" +} + +// @filename: /project/tsconfig.json +{ + "compilerOptions": { + "outDir": "lib" + }, + "include": ["src"] +} + +// @filename: /project/src/index.ts +export const value = 0; From e2b31a58a111f8a3768e9a8bd9aa8c5f40887839 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 10:44:31 -0700 Subject: [PATCH 104/116] Add coverage for require-to-types exports fallback Origin: https://redirect.github.com/microsoft/TypeScript/pull/62310#issuecomment-3251203783 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...itionalExportsRequireTypesFallback.symbols | 13 +++++++++++ ...onalExportsRequireTypesFallback.trace.json | 21 ++++++++++++++++++ ...nditionalExportsRequireTypesFallback.types | 13 +++++++++++ .../conditionalExportsRequireTypesFallback.ts | 22 +++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.trace.json create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.types create mode 100644 tsc/testdata/tests/cases/compiler/conditionalExportsRequireTypesFallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.symbols b/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.symbols new file mode 100644 index 0000000000000..dedbedd3aa8a8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.symbols @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/conditionalExportsRequireTypesFallback.ts] //// + +=== /index.cts === +import { value } from "provider"; +>value : Symbol(value, Decl(index.cts, 0, 8)) + +value; +>value : Symbol(value, Decl(index.cts, 0, 8)) + +=== /node_modules/provider/index.d.ts === +export const value: number; +>value : Symbol(value, Decl(index.d.ts, 0, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.trace.json b/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.trace.json new file mode 100644 index 0000000000000..4d0a84f727021 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.trace.json @@ -0,0 +1,21 @@ +======== Resolving module 'provider' from '/index.cts'. ======== +Explicitly specified module resolution kind: 'NodeNext'. +Resolving in CJS mode with conditions 'require', 'types', 'node'. +File '/package.json' does not exist. +Loading module 'provider' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON. +Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration. +Found 'package.json' at '/node_modules/provider/package.json'. +Entering conditional exports. +Matched 'exports' condition 'require'. +Using 'exports' subpath '.' with target './index.cjs'. +File name '/node_modules/provider/index.cjs' has a '.cjs' extension - stripping it. +File '/node_modules/provider/index.cts' does not exist. +File '/node_modules/provider/index.d.cts' does not exist. +Failed to resolve under condition 'require'. +Matched 'exports' condition 'types'. +Using 'exports' subpath '.' with target './index.d.ts'. +File '/node_modules/provider/index.d.ts' exists - use it as a name resolution result. +Resolved under condition 'types'. +Exiting conditional exports. +Resolving real path for '/node_modules/provider/index.d.ts', result '/node_modules/provider/index.d.ts'. +======== Module name 'provider' was successfully resolved to '/node_modules/provider/index.d.ts'. ======== diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.types b/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.types new file mode 100644 index 0000000000000..ff3e0151205c4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsRequireTypesFallback.types @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/conditionalExportsRequireTypesFallback.ts] //// + +=== /index.cts === +import { value } from "provider"; +>value : number + +value; +>value : number + +=== /node_modules/provider/index.d.ts === +export const value: number; +>value : number + diff --git a/tsc/testdata/tests/cases/compiler/conditionalExportsRequireTypesFallback.ts b/tsc/testdata/tests/cases/compiler/conditionalExportsRequireTypesFallback.ts new file mode 100644 index 0000000000000..28cd35d289928 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/conditionalExportsRequireTypesFallback.ts @@ -0,0 +1,22 @@ +// @target: es2015 +// @module: nodenext +// @moduleResolution: nodenext +// @strict: true +// @noEmit: true +// @traceResolution: true +// @noImplicitReferences: true + +// @filename: /node_modules/provider/package.json +{ + "exports": { + "require": "./index.cjs", + "types": "./index.d.ts" + } +} +// @filename: /node_modules/provider/index.cjs +exports.value = 0; +// @filename: /node_modules/provider/index.d.ts +export const value: number; +// @filename: /index.cts +import { value } from "provider"; +value; From 0c1d7836cd03d55400928d1e37095db1939dbe9b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 10:44:35 -0700 Subject: [PATCH 105/116] Add coverage for node-to-types exports fallback Origin: https://redirect.github.com/microsoft/TypeScript/pull/62310#issuecomment-3251203808 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...onditionalExportsNodeTypesFallback.symbols | 13 +++++++++++ ...itionalExportsNodeTypesFallback.trace.json | 22 +++++++++++++++++++ .../conditionalExportsNodeTypesFallback.types | 13 +++++++++++ .../conditionalExportsNodeTypesFallback.ts | 22 +++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.trace.json create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.types create mode 100644 tsc/testdata/tests/cases/compiler/conditionalExportsNodeTypesFallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.symbols b/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.symbols new file mode 100644 index 0000000000000..9d42e36f1fd29 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.symbols @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/conditionalExportsNodeTypesFallback.ts] //// + +=== /index.mts === +import { value } from "provider"; +>value : Symbol(value, Decl(index.mts, 0, 8)) + +value; +>value : Symbol(value, Decl(index.mts, 0, 8)) + +=== /node_modules/provider/types.d.ts === +export const value: number; +>value : Symbol(value, Decl(types.d.ts, 0, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.trace.json b/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.trace.json new file mode 100644 index 0000000000000..3cbcade3af3db --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.trace.json @@ -0,0 +1,22 @@ +======== Resolving module 'provider' from '/index.mts'. ======== +Explicitly specified module resolution kind: 'NodeNext'. +Resolving in ESM mode with conditions 'import', 'types', 'node'. +File '/package.json' does not exist. +Loading module 'provider' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON. +Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration. +Found 'package.json' at '/node_modules/provider/package.json'. +Entering conditional exports. +Matched 'exports' condition 'node'. +Using 'exports' subpath '.' with target './index.js'. +File name '/node_modules/provider/index.js' has a '.js' extension - stripping it. +File '/node_modules/provider/index.ts' does not exist. +File '/node_modules/provider/index.tsx' does not exist. +File '/node_modules/provider/index.d.ts' does not exist. +Failed to resolve under condition 'node'. +Matched 'exports' condition 'types'. +Using 'exports' subpath '.' with target './types.d.ts'. +File '/node_modules/provider/types.d.ts' exists - use it as a name resolution result. +Resolved under condition 'types'. +Exiting conditional exports. +Resolving real path for '/node_modules/provider/types.d.ts', result '/node_modules/provider/types.d.ts'. +======== Module name 'provider' was successfully resolved to '/node_modules/provider/types.d.ts'. ======== diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.types b/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.types new file mode 100644 index 0000000000000..c692f2c478592 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsNodeTypesFallback.types @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/conditionalExportsNodeTypesFallback.ts] //// + +=== /index.mts === +import { value } from "provider"; +>value : number + +value; +>value : number + +=== /node_modules/provider/types.d.ts === +export const value: number; +>value : number + diff --git a/tsc/testdata/tests/cases/compiler/conditionalExportsNodeTypesFallback.ts b/tsc/testdata/tests/cases/compiler/conditionalExportsNodeTypesFallback.ts new file mode 100644 index 0000000000000..def40bb08b452 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/conditionalExportsNodeTypesFallback.ts @@ -0,0 +1,22 @@ +// @target: es2015 +// @module: nodenext +// @moduleResolution: nodenext +// @strict: true +// @noEmit: true +// @traceResolution: true +// @noImplicitReferences: true + +// @filename: /node_modules/provider/package.json +{ + "exports": { + "node": "./index.js", + "types": "./types.d.ts" + } +} +// @filename: /node_modules/provider/index.js +exports.value = 0; +// @filename: /node_modules/provider/types.d.ts +export const value: number; +// @filename: /index.mts +import { value } from "provider"; +value; From 6bb608f0adee5b6e782c379ef01a284e650ec57a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 10:44:39 -0700 Subject: [PATCH 106/116] Add coverage for types-to-import exports fallback Origin: https://redirect.github.com/microsoft/TypeScript/pull/62310#issuecomment-3251203783 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...ditionalExportsTypesImportFallback.symbols | 16 ++++++++++++ ...ionalExportsTypesImportFallback.trace.json | 21 +++++++++++++++ ...onditionalExportsTypesImportFallback.types | 16 ++++++++++++ .../conditionalExportsTypesImportFallback.ts | 26 +++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.trace.json create mode 100644 tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.types create mode 100644 tsc/testdata/tests/cases/compiler/conditionalExportsTypesImportFallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.symbols b/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.symbols new file mode 100644 index 0000000000000..5d370eeb27dcd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/conditionalExportsTypesImportFallback.ts] //// + +=== /index.mts === +import color from "theme/tokens"; +>color : Symbol(color, Decl(index.mts, 0, 6)) + +color; +>color : Symbol(color, Decl(index.mts, 0, 6)) + +=== /node_modules/theme/tokens.d.mts === +declare const color: string; +>color : Symbol(color, Decl(tokens.d.mts, 0, 13)) + +export default color; +>color : Symbol(color, Decl(tokens.d.mts, 0, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.trace.json b/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.trace.json new file mode 100644 index 0000000000000..421bc7aed330a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.trace.json @@ -0,0 +1,21 @@ +======== Resolving module 'theme/tokens' from '/index.mts'. ======== +Explicitly specified module resolution kind: 'Bundler'. +Resolving in CJS mode with conditions 'import', 'types'. +File '/package.json' does not exist. +Loading module 'theme/tokens' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON. +Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration. +Found 'package.json' at '/node_modules/theme/package.json'. +Entering conditional exports. +Matched 'exports' condition 'types'. +Using 'exports' subpath './tokens' with target './tokens.d.ts'. +File '/node_modules/theme/tokens.d.ts' does not exist. +Failed to resolve under condition 'types'. +Matched 'exports' condition 'import'. +Using 'exports' subpath './tokens' with target './tokens.mjs'. +File name '/node_modules/theme/tokens.mjs' has a '.mjs' extension - stripping it. +File '/node_modules/theme/tokens.mts' does not exist. +File '/node_modules/theme/tokens.d.mts' exists - use it as a name resolution result. +Resolved under condition 'import'. +Exiting conditional exports. +Resolving real path for '/node_modules/theme/tokens.d.mts', result '/node_modules/theme/tokens.d.mts'. +======== Module name 'theme/tokens' was successfully resolved to '/node_modules/theme/tokens.d.mts'. ======== diff --git a/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.types b/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.types new file mode 100644 index 0000000000000..7c8e954a6303e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/conditionalExportsTypesImportFallback.types @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/conditionalExportsTypesImportFallback.ts] //// + +=== /index.mts === +import color from "theme/tokens"; +>color : string + +color; +>color : string + +=== /node_modules/theme/tokens.d.mts === +declare const color: string; +>color : string + +export default color; +>color : string + diff --git a/tsc/testdata/tests/cases/compiler/conditionalExportsTypesImportFallback.ts b/tsc/testdata/tests/cases/compiler/conditionalExportsTypesImportFallback.ts new file mode 100644 index 0000000000000..70f0e07dd3b92 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/conditionalExportsTypesImportFallback.ts @@ -0,0 +1,26 @@ +// @target: es2015 +// @module: esnext +// @moduleResolution: bundler +// @strict: true +// @noEmit: true +// @traceResolution: true +// @noImplicitReferences: true + +// @filename: /node_modules/theme/package.json +{ + "exports": { + "./tokens": { + "types": "./tokens.d.ts", + "import": "./tokens.mjs", + "default": "./tokens.mjs" + } + } +} +// @filename: /node_modules/theme/tokens.mjs +export default "blue"; +// @filename: /node_modules/theme/tokens.d.mts +declare const color: string; +export default color; +// @filename: /index.mts +import color from "theme/tokens"; +color; From 2e435c1149e878bc18c53115d9f4f7923f1fd95f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 10:44:43 -0700 Subject: [PATCH 107/116] Cover base globals lost through excluded automatic types Origin: https://redirect.github.com/microsoft/TypeScript/pull/63054#issuecomment-3808836321 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- ...pesExcludeBaseLibraryReferences.errors.txt | 20 +++++++++++++++++++ ...tTypesExcludeBaseLibraryReferences.symbols | 6 ++++++ ...ultTypesExcludeBaseLibraryReferences.types | 6 ++++++ ...efaultTypesExcludeBaseLibraryReferences.ts | 13 ++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.errors.txt b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.errors.txt new file mode 100644 index 0000000000000..75bdcdc5361ab --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.errors.txt @@ -0,0 +1,20 @@ +error TS2318: Cannot find global type 'Boolean'. +error TS2318: Cannot find global type 'CallableFunction'. +error TS2318: Cannot find global type 'IArguments'. +error TS2318: Cannot find global type 'NewableFunction'. +error TS2318: Cannot find global type 'Number'. +error TS2318: Cannot find global type 'Object'. + + +!!! error TS2318: Cannot find global type 'Boolean'. +!!! error TS2318: Cannot find global type 'CallableFunction'. +!!! error TS2318: Cannot find global type 'IArguments'. +!!! error TS2318: Cannot find global type 'NewableFunction'. +!!! error TS2318: Cannot find global type 'Number'. +!!! error TS2318: Cannot find global type 'Object'. +==== /main.ts (0 errors) ==== + export {}; + +==== /node_modules/@types/runtime/index.d.ts (0 errors) ==== + /// + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.symbols b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.symbols new file mode 100644 index 0000000000000..0609c95cf6c15 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.symbols @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts] //// + +=== /main.ts === + +export {}; + diff --git a/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.types b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.types new file mode 100644 index 0000000000000..0609c95cf6c15 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultTypesExcludeBaseLibraryReferences.types @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts] //// + +=== /main.ts === + +export {}; + diff --git a/tsc/testdata/tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts new file mode 100644 index 0000000000000..08da07c65aaa2 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts @@ -0,0 +1,13 @@ +// @target: es2015 +// @lib: es2021.weakref +// @module: commonjs +// @strict: true +// @skipLibCheck: true +// @noEmit: true +// @noImplicitReferences: true + +// @filename: /node_modules/@types/runtime/index.d.ts +/// + +// @filename: /main.ts +export {}; From 3d0d35ae94202e0d6c650c87da46dc554ebdea3b Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 11:20:30 -0700 Subject: [PATCH 108/116] Add direct external-files config-root coverage Exercise omitted noncomposite rootDir with an explicit files entry outside the configuration directory and a local outDir. Retain the files-list related location and current migration diagnostic. Complements inherited-include coverage without claiming a new primary TS6059 mechanism or a full installed-project replay. Origin: https://redirect.github.com/microsoft/TypeScript/pull/62418#issuecomment-3572538356 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../defaultRootDirExternalFiles.errors.txt | 25 +++++++++++++++++++ .../compiler/defaultRootDirExternalFiles.js | 8 ++++++ .../defaultRootDirExternalFiles.symbols | 6 +++++ .../defaultRootDirExternalFiles.types | 7 ++++++ .../compiler/defaultRootDirExternalFiles.ts | 12 +++++++++ 5 files changed, 58 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.js create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.types create mode 100644 tsc/testdata/tests/cases/compiler/defaultRootDirExternalFiles.ts diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.errors.txt b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.errors.txt new file mode 100644 index 0000000000000..e01a680e9d0ed --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.errors.txt @@ -0,0 +1,25 @@ +error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files. + The file is in the program because: + Part of 'files' list in tsconfig.json +/project/example/tsconfig.json(3,9): error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout. + Visit https://aka.ms/ts6 for migration information. + + +!!! error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files. +!!! error TS6059: The file is in the program because: +!!! error TS6059: Part of 'files' list in tsconfig.json +!!! related TS1410 /project/example/tsconfig.json:5:15: File is matched by 'files' list specified here. +==== /project/example/tsconfig.json (1 errors) ==== + { + "compilerOptions": { + "outDir": "." + ~~~~~~~~ +!!! error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout. +!!! error TS5011: Visit https://aka.ms/ts6 for migration information. + }, + "files": ["../src/index.ts"] + } + +==== /project/src/index.ts (0 errors) ==== + export const value = 0; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.js b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.js new file mode 100644 index 0000000000000..fe1458d3c6ae3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.js @@ -0,0 +1,8 @@ +//// [tests/cases/compiler/defaultRootDirExternalFiles.ts] //// + +//// [index.ts] +export const value = 0; + + +//// [index.js] +export const value = 0; diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.symbols b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.symbols new file mode 100644 index 0000000000000..21796d308a5c8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.symbols @@ -0,0 +1,6 @@ +//// [tests/cases/compiler/defaultRootDirExternalFiles.ts] //// + +=== /project/src/index.ts === +export const value = 0; +>value : Symbol(value, Decl(index.ts, 0, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.types b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.types new file mode 100644 index 0000000000000..8950714816e45 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/defaultRootDirExternalFiles.types @@ -0,0 +1,7 @@ +//// [tests/cases/compiler/defaultRootDirExternalFiles.ts] //// + +=== /project/src/index.ts === +export const value = 0; +>value : 0 +>0 : 0 + diff --git a/tsc/testdata/tests/cases/compiler/defaultRootDirExternalFiles.ts b/tsc/testdata/tests/cases/compiler/defaultRootDirExternalFiles.ts new file mode 100644 index 0000000000000..bdc891bdb89ea --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/defaultRootDirExternalFiles.ts @@ -0,0 +1,12 @@ +// @currentDirectory: /project + +// @filename: /project/example/tsconfig.json +{ + "compilerOptions": { + "outDir": "." + }, + "files": ["../src/index.ts"] +} + +// @filename: /project/src/index.ts +export const value = 0; From 2b678d9ae49ce9bfb489d338c875d8f7ca547402 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 12:07:51 -0700 Subject: [PATCH 109/116] Cover generic calls after excluding strings Preserve inference for a generic identity call from the negative typeof-string branch on unknown. Reduced from Presenton's recursive asset normalizer reported by the negated-types experiment. Origin: https://redirect.github.com/microsoft/TypeScript/pull/63926#issuecomment-5688566241 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../genericCallInNegativeTypeofBranch.js | 14 +++++++++++ .../genericCallInNegativeTypeofBranch.symbols | 21 +++++++++++++++++ .../genericCallInNegativeTypeofBranch.types | 23 +++++++++++++++++++ .../genericCallInNegativeTypeofBranch.ts | 6 +++++ 4 files changed, 64 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.js create mode 100644 tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types create mode 100644 tsc/testdata/tests/cases/compiler/genericCallInNegativeTypeofBranch.ts diff --git a/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.js b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.js new file mode 100644 index 0000000000000..60ced5af62d05 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.js @@ -0,0 +1,14 @@ +//// [tests/cases/compiler/genericCallInNegativeTypeofBranch.ts] //// + +//// [genericCallInNegativeTypeofBranch.ts] +declare function identity(value: T): T; +function normalize(value: unknown) { + return typeof value === "string" ? value : identity(value); +} + + +//// [genericCallInNegativeTypeofBranch.js] +"use strict"; +function normalize(value) { + return typeof value === "string" ? value : identity(value); +} diff --git a/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.symbols b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.symbols new file mode 100644 index 0000000000000..46129c3d630f9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/genericCallInNegativeTypeofBranch.ts] //// + +=== genericCallInNegativeTypeofBranch.ts === +declare function identity(value: T): T; +>identity : Symbol(identity, Decl(genericCallInNegativeTypeofBranch.ts, 0, 0)) +>T : Symbol(T, Decl(genericCallInNegativeTypeofBranch.ts, 0, 26)) +>value : Symbol(value, Decl(genericCallInNegativeTypeofBranch.ts, 0, 29)) +>T : Symbol(T, Decl(genericCallInNegativeTypeofBranch.ts, 0, 26)) +>T : Symbol(T, Decl(genericCallInNegativeTypeofBranch.ts, 0, 26)) + +function normalize(value: unknown) { +>normalize : Symbol(normalize, Decl(genericCallInNegativeTypeofBranch.ts, 0, 42)) +>value : Symbol(value, Decl(genericCallInNegativeTypeofBranch.ts, 1, 19)) + + return typeof value === "string" ? value : identity(value); +>value : Symbol(value, Decl(genericCallInNegativeTypeofBranch.ts, 1, 19)) +>value : Symbol(value, Decl(genericCallInNegativeTypeofBranch.ts, 1, 19)) +>identity : Symbol(identity, Decl(genericCallInNegativeTypeofBranch.ts, 0, 0)) +>value : Symbol(value, Decl(genericCallInNegativeTypeofBranch.ts, 1, 19)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types new file mode 100644 index 0000000000000..d057373eefd39 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/genericCallInNegativeTypeofBranch.ts] //// + +=== genericCallInNegativeTypeofBranch.ts === +declare function identity(value: T): T; +>identity : (value: T) => T +>value : T + +function normalize(value: unknown) { +>normalize : (value: unknown) => unknown +>value : unknown + + return typeof value === "string" ? value : identity(value); +>typeof value === "string" ? value : identity(value) : unknown +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" +>value : string +>identity(value) : unknown +>identity : (value: T) => T +>value : unknown +} + diff --git a/tsc/testdata/tests/cases/compiler/genericCallInNegativeTypeofBranch.ts b/tsc/testdata/tests/cases/compiler/genericCallInNegativeTypeofBranch.ts new file mode 100644 index 0000000000000..45681db2f3134 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/genericCallInNegativeTypeofBranch.ts @@ -0,0 +1,6 @@ +// @strict: true + +declare function identity(value: T): T; +function normalize(value: unknown) { + return typeof value === "string" ? value : identity(value); +} From e846065f47e0add902aa7bbbb4073ef6dfd7a2db Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:04:37 -0700 Subject: [PATCH 110/116] Add coverage for optional regex captures assigned to string arrays Origin: https://redirect.github.com/microsoft/TypeScript/pull/60249#issuecomment-2467177299 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/regexpOptionalCaptureStringArray.js | 9 +++++++++ .../compiler/regexpOptionalCaptureStringArray.symbols | 8 ++++++++ .../compiler/regexpOptionalCaptureStringArray.types | 11 +++++++++++ .../compiler/regexpOptionalCaptureStringArray.ts | 3 +++ 4 files changed, 31 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.js create mode 100644 tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.types create mode 100644 tsc/testdata/tests/cases/compiler/regexpOptionalCaptureStringArray.ts diff --git a/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.js b/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.js new file mode 100644 index 0000000000000..0ad730ad2fdd5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.js @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/regexpOptionalCaptureStringArray.ts] //// + +//// [regexpOptionalCaptureStringArray.ts] +const result: string[] | null = /^(a)?$/.exec(""); + + +//// [regexpOptionalCaptureStringArray.js] +"use strict"; +const result = /^(a)?$/.exec(""); diff --git a/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.symbols b/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.symbols new file mode 100644 index 0000000000000..9d6fe5c746e1e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.symbols @@ -0,0 +1,8 @@ +//// [tests/cases/compiler/regexpOptionalCaptureStringArray.ts] //// + +=== regexpOptionalCaptureStringArray.ts === +const result: string[] | null = /^(a)?$/.exec(""); +>result : Symbol(result, Decl(regexpOptionalCaptureStringArray.ts, 0, 5)) +>/^(a)?$/.exec : Symbol(RegExp.exec, Decl(lib.es5.d.ts, --, --)) +>exec : Symbol(RegExp.exec, Decl(lib.es5.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.types b/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.types new file mode 100644 index 0000000000000..652a64f384f4b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpOptionalCaptureStringArray.types @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/regexpOptionalCaptureStringArray.ts] //// + +=== regexpOptionalCaptureStringArray.ts === +const result: string[] | null = /^(a)?$/.exec(""); +>result : string[] | null +>/^(a)?$/.exec("") : RegExpExecArray | null +>/^(a)?$/.exec : (string: string) => RegExpExecArray | null +>/^(a)?$/ : RegExp +>exec : (string: string) => RegExpExecArray | null +>"" : "" + diff --git a/tsc/testdata/tests/cases/compiler/regexpOptionalCaptureStringArray.ts b/tsc/testdata/tests/cases/compiler/regexpOptionalCaptureStringArray.ts new file mode 100644 index 0000000000000..107f62dd47b0b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/regexpOptionalCaptureStringArray.ts @@ -0,0 +1,3 @@ +// @strict: true + +const result: string[] | null = /^(a)?$/.exec(""); From e9c6b9840d340bd7ca9cd2c827997c8ffad8a14d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:04:41 -0700 Subject: [PATCH 111/116] Add coverage for structural TreeWalker mocks Origin: https://redirect.github.com/microsoft/TypeScript/pull/62682#issuecomment-3458174971 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/domTreeWalkerStructuralMock.js | 24 ++++++++ .../domTreeWalkerStructuralMock.symbols | 60 +++++++++++++++++++ .../domTreeWalkerStructuralMock.types | 47 +++++++++++++++ .../compiler/domTreeWalkerStructuralMock.ts | 19 ++++++ 4 files changed, 150 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.js create mode 100644 tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.types create mode 100644 tsc/testdata/tests/cases/compiler/domTreeWalkerStructuralMock.ts diff --git a/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.js b/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.js new file mode 100644 index 0000000000000..6a3d0199c6ba0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/domTreeWalkerStructuralMock.ts] //// + +//// [domTreeWalkerStructuralMock.ts] +declare class Walker implements TreeWalker { + currentNode: Node; + readonly filter: NodeFilter | null; + readonly root: Node; + readonly whatToShow: number; + firstChild(): Node | null; + lastChild(): Node | null; + nextNode(): Node | null; + nextSibling(): Node | null; + parentNode(): Node | null; + previousNode(): Node | null; + previousSibling(): Node | null; +} + +declare const walker: Walker; +const result: TreeWalker = walker; + + +//// [domTreeWalkerStructuralMock.js] +"use strict"; +const result = walker; diff --git a/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.symbols b/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.symbols new file mode 100644 index 0000000000000..c7ef322341b1e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.symbols @@ -0,0 +1,60 @@ +//// [tests/cases/compiler/domTreeWalkerStructuralMock.ts] //// + +=== domTreeWalkerStructuralMock.ts === +declare class Walker implements TreeWalker { +>Walker : Symbol(Walker, Decl(domTreeWalkerStructuralMock.ts, 0, 0)) +>TreeWalker : Symbol(TreeWalker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + currentNode: Node; +>currentNode : Symbol(Walker.currentNode, Decl(domTreeWalkerStructuralMock.ts, 0, 44)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + readonly filter: NodeFilter | null; +>filter : Symbol(Walker.filter, Decl(domTreeWalkerStructuralMock.ts, 1, 22)) +>NodeFilter : Symbol(NodeFilter, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + readonly root: Node; +>root : Symbol(Walker.root, Decl(domTreeWalkerStructuralMock.ts, 2, 39)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + readonly whatToShow: number; +>whatToShow : Symbol(Walker.whatToShow, Decl(domTreeWalkerStructuralMock.ts, 3, 24)) + + firstChild(): Node | null; +>firstChild : Symbol(Walker.firstChild, Decl(domTreeWalkerStructuralMock.ts, 4, 32)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + lastChild(): Node | null; +>lastChild : Symbol(Walker.lastChild, Decl(domTreeWalkerStructuralMock.ts, 5, 30)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + nextNode(): Node | null; +>nextNode : Symbol(Walker.nextNode, Decl(domTreeWalkerStructuralMock.ts, 6, 29)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + nextSibling(): Node | null; +>nextSibling : Symbol(Walker.nextSibling, Decl(domTreeWalkerStructuralMock.ts, 7, 28)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + parentNode(): Node | null; +>parentNode : Symbol(Walker.parentNode, Decl(domTreeWalkerStructuralMock.ts, 8, 31)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + previousNode(): Node | null; +>previousNode : Symbol(Walker.previousNode, Decl(domTreeWalkerStructuralMock.ts, 9, 30)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + previousSibling(): Node | null; +>previousSibling : Symbol(Walker.previousSibling, Decl(domTreeWalkerStructuralMock.ts, 10, 32)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +} + +declare const walker: Walker; +>walker : Symbol(walker, Decl(domTreeWalkerStructuralMock.ts, 14, 13)) +>Walker : Symbol(Walker, Decl(domTreeWalkerStructuralMock.ts, 0, 0)) + +const result: TreeWalker = walker; +>result : Symbol(result, Decl(domTreeWalkerStructuralMock.ts, 15, 5)) +>TreeWalker : Symbol(TreeWalker, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>walker : Symbol(walker, Decl(domTreeWalkerStructuralMock.ts, 14, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.types b/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.types new file mode 100644 index 0000000000000..4c95e36226e76 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domTreeWalkerStructuralMock.types @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/domTreeWalkerStructuralMock.ts] //// + +=== domTreeWalkerStructuralMock.ts === +declare class Walker implements TreeWalker { +>Walker : Walker + + currentNode: Node; +>currentNode : Node + + readonly filter: NodeFilter | null; +>filter : NodeFilter | null + + readonly root: Node; +>root : Node + + readonly whatToShow: number; +>whatToShow : number + + firstChild(): Node | null; +>firstChild : () => Node | null + + lastChild(): Node | null; +>lastChild : () => Node | null + + nextNode(): Node | null; +>nextNode : () => Node | null + + nextSibling(): Node | null; +>nextSibling : () => Node | null + + parentNode(): Node | null; +>parentNode : () => Node | null + + previousNode(): Node | null; +>previousNode : () => Node | null + + previousSibling(): Node | null; +>previousSibling : () => Node | null +} + +declare const walker: Walker; +>walker : Walker + +const result: TreeWalker = walker; +>result : TreeWalker +>walker : Walker + diff --git a/tsc/testdata/tests/cases/compiler/domTreeWalkerStructuralMock.ts b/tsc/testdata/tests/cases/compiler/domTreeWalkerStructuralMock.ts new file mode 100644 index 0000000000000..7d756addece32 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domTreeWalkerStructuralMock.ts @@ -0,0 +1,19 @@ +// @target: es2015 +// @strict: true + +declare class Walker implements TreeWalker { + currentNode: Node; + readonly filter: NodeFilter | null; + readonly root: Node; + readonly whatToShow: number; + firstChild(): Node | null; + lastChild(): Node | null; + nextNode(): Node | null; + nextSibling(): Node | null; + parentNode(): Node | null; + previousNode(): Node | null; + previousSibling(): Node | null; +} + +declare const walker: Walker; +const result: TreeWalker = walker; From 2a6f82bb1d74ed8e9cee8747558a5922f4c6ead3 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:24:25 -0700 Subject: [PATCH 112/116] Add coverage for string-only keys of DOM Elements Origin: https://redirect.github.com/microsoft/TypeScript/pull/62682#issuecomment-3458174971 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/domElementStringKeyConstraint.js | 12 ++++++++ .../domElementStringKeyConstraint.symbols | 30 +++++++++++++++++++ .../domElementStringKeyConstraint.types | 22 ++++++++++++++ .../compiler/domElementStringKeyConstraint.ts | 7 +++++ 4 files changed, 71 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.js create mode 100644 tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.types create mode 100644 tsc/testdata/tests/cases/compiler/domElementStringKeyConstraint.ts diff --git a/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.js b/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.js new file mode 100644 index 0000000000000..a200d2d37dc84 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/domElementStringKeyConstraint.ts] //// + +//// [domElementStringKeyConstraint.ts] +declare function setProperty(element: T, property: K, value: T[K]): void; +declare const element: Element; +declare const key: keyof Element; +setProperty(element, key, true); + + +//// [domElementStringKeyConstraint.js] +"use strict"; +setProperty(element, key, true); diff --git a/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.symbols b/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.symbols new file mode 100644 index 0000000000000..4cb2a7b66b102 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.symbols @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/domElementStringKeyConstraint.ts] //// + +=== domElementStringKeyConstraint.ts === +declare function setProperty(element: T, property: K, value: T[K]): void; +>setProperty : Symbol(setProperty, Decl(domElementStringKeyConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(domElementStringKeyConstraint.ts, 0, 29)) +>Element : Symbol(Element, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>K : Symbol(K, Decl(domElementStringKeyConstraint.ts, 0, 47)) +>T : Symbol(T, Decl(domElementStringKeyConstraint.ts, 0, 29)) +>element : Symbol(element, Decl(domElementStringKeyConstraint.ts, 0, 76)) +>T : Symbol(T, Decl(domElementStringKeyConstraint.ts, 0, 29)) +>property : Symbol(property, Decl(domElementStringKeyConstraint.ts, 0, 87)) +>K : Symbol(K, Decl(domElementStringKeyConstraint.ts, 0, 47)) +>value : Symbol(value, Decl(domElementStringKeyConstraint.ts, 0, 100)) +>T : Symbol(T, Decl(domElementStringKeyConstraint.ts, 0, 29)) +>K : Symbol(K, Decl(domElementStringKeyConstraint.ts, 0, 47)) + +declare const element: Element; +>element : Symbol(element, Decl(domElementStringKeyConstraint.ts, 1, 13)) +>Element : Symbol(Element, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +declare const key: keyof Element; +>key : Symbol(key, Decl(domElementStringKeyConstraint.ts, 2, 13)) +>Element : Symbol(Element, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +setProperty(element, key, true); +>setProperty : Symbol(setProperty, Decl(domElementStringKeyConstraint.ts, 0, 0)) +>element : Symbol(element, Decl(domElementStringKeyConstraint.ts, 1, 13)) +>key : Symbol(key, Decl(domElementStringKeyConstraint.ts, 2, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.types b/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.types new file mode 100644 index 0000000000000..99863978a49e3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domElementStringKeyConstraint.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/domElementStringKeyConstraint.ts] //// + +=== domElementStringKeyConstraint.ts === +declare function setProperty(element: T, property: K, value: T[K]): void; +>setProperty : (element: T, property: K, value: T[K]) => void +>element : T +>property : K +>value : T[K] + +declare const element: Element; +>element : Element + +declare const key: keyof Element; +>key : keyof Element + +setProperty(element, key, true); +>setProperty(element, key, true) : void +>setProperty : (element: T, property: K, value: T[K]) => void +>element : Element +>key : keyof Element +>true : true + diff --git a/tsc/testdata/tests/cases/compiler/domElementStringKeyConstraint.ts b/tsc/testdata/tests/cases/compiler/domElementStringKeyConstraint.ts new file mode 100644 index 0000000000000..76506fc8f7177 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domElementStringKeyConstraint.ts @@ -0,0 +1,7 @@ +// @target: es2015 +// @strict: true + +declare function setProperty(element: T, property: K, value: T[K]): void; +declare const element: Element; +declare const key: keyof Element; +setProperty(element, key, true); From 39f81f514aec1a12da9f0cb1b40dfb158ecc07d0 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:48:26 -0700 Subject: [PATCH 113/116] Add historical DOM base-element assignment coverage Preserve structural assignment compatibility from HTMLElement to HTMLSpanElement. Source: https://redirect.github.com/microsoft/TypeScript/pull/62682#issuecomment-3458175031 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../reference/compiler/domBaseElementToSpan.js | 10 ++++++++++ .../reference/compiler/domBaseElementToSpan.symbols | 12 ++++++++++++ .../reference/compiler/domBaseElementToSpan.types | 10 ++++++++++ .../tests/cases/compiler/domBaseElementToSpan.ts | 5 +++++ 4 files changed, 37 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.js create mode 100644 tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.types create mode 100644 tsc/testdata/tests/cases/compiler/domBaseElementToSpan.ts diff --git a/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.js b/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.js new file mode 100644 index 0000000000000..434821cf24a4f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.js @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/domBaseElementToSpan.ts] //// + +//// [domBaseElementToSpan.ts] +declare const element: HTMLElement; +const span: HTMLSpanElement = element; + + +//// [domBaseElementToSpan.js] +"use strict"; +const span = element; diff --git a/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.symbols b/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.symbols new file mode 100644 index 0000000000000..6b0cbd7fad421 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.symbols @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/domBaseElementToSpan.ts] //// + +=== domBaseElementToSpan.ts === +declare const element: HTMLElement; +>element : Symbol(element, Decl(domBaseElementToSpan.ts, 0, 13)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +const span: HTMLSpanElement = element; +>span : Symbol(span, Decl(domBaseElementToSpan.ts, 1, 5)) +>HTMLSpanElement : Symbol(HTMLSpanElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>element : Symbol(element, Decl(domBaseElementToSpan.ts, 0, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.types b/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.types new file mode 100644 index 0000000000000..6f70e2948c150 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/domBaseElementToSpan.types @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/domBaseElementToSpan.ts] //// + +=== domBaseElementToSpan.ts === +declare const element: HTMLElement; +>element : HTMLElement + +const span: HTMLSpanElement = element; +>span : HTMLSpanElement +>element : HTMLElement + diff --git a/tsc/testdata/tests/cases/compiler/domBaseElementToSpan.ts b/tsc/testdata/tests/cases/compiler/domBaseElementToSpan.ts new file mode 100644 index 0000000000000..2e712e407db5d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/domBaseElementToSpan.ts @@ -0,0 +1,5 @@ +// @target: es2015 +// @strict: true + +declare const element: HTMLElement; +const span: HTMLSpanElement = element; From bd8b1f64272db2ddd87b5def9b2364437157e81f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:48:30 -0700 Subject: [PATCH 114/116] Add historical single-parameter replacement callback coverage Accept a pretyped single-string callback when replacing with a broad RegExp. Source: https://redirect.github.com/microsoft/TypeScript/pull/60249#issuecomment-2467177299 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../regexpReplaceSingleParameterCallback.js | 11 +++++++++++ ...egexpReplaceSingleParameterCallback.symbols | 17 +++++++++++++++++ .../regexpReplaceSingleParameterCallback.types | 18 ++++++++++++++++++ .../regexpReplaceSingleParameterCallback.ts | 6 ++++++ 4 files changed, 52 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.js create mode 100644 tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.types create mode 100644 tsc/testdata/tests/cases/compiler/regexpReplaceSingleParameterCallback.ts diff --git a/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.js b/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.js new file mode 100644 index 0000000000000..74aae3a82c05e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.js @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/regexpReplaceSingleParameterCallback.ts] //// + +//// [regexpReplaceSingleParameterCallback.ts] +declare const pattern: RegExp; +declare const replace: (value: string) => string; +"".replace(pattern, replace); + + +//// [regexpReplaceSingleParameterCallback.js] +"use strict"; +"".replace(pattern, replace); diff --git a/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.symbols b/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.symbols new file mode 100644 index 0000000000000..1cf44d81cd117 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/regexpReplaceSingleParameterCallback.ts] //// + +=== regexpReplaceSingleParameterCallback.ts === +declare const pattern: RegExp; +>pattern : Symbol(pattern, Decl(regexpReplaceSingleParameterCallback.ts, 0, 13)) +>RegExp : Symbol(RegExp, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +declare const replace: (value: string) => string; +>replace : Symbol(replace, Decl(regexpReplaceSingleParameterCallback.ts, 1, 13)) +>value : Symbol(value, Decl(regexpReplaceSingleParameterCallback.ts, 1, 24)) + +"".replace(pattern, replace); +>"".replace : Symbol(String.replace, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>replace : Symbol(String.replace, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>pattern : Symbol(pattern, Decl(regexpReplaceSingleParameterCallback.ts, 0, 13)) +>replace : Symbol(replace, Decl(regexpReplaceSingleParameterCallback.ts, 1, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.types b/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.types new file mode 100644 index 0000000000000..2d584052b5dba --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpReplaceSingleParameterCallback.types @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/regexpReplaceSingleParameterCallback.ts] //// + +=== regexpReplaceSingleParameterCallback.ts === +declare const pattern: RegExp; +>pattern : RegExp + +declare const replace: (value: string) => string; +>replace : (value: string) => string +>value : string + +"".replace(pattern, replace); +>"".replace(pattern, replace) : string +>"".replace : { (searchValue: string | RegExp, replaceValue: string): string; (searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string; (searchValue: { [Symbol.replace](string: string, replaceValue: string): string; }, replaceValue: string): string; (searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string; } +>"" : "" +>replace : { (searchValue: string | RegExp, replaceValue: string): string; (searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string; (searchValue: { [Symbol.replace](string: string, replaceValue: string): string; }, replaceValue: string): string; (searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string; } +>pattern : RegExp +>replace : (value: string) => string + diff --git a/tsc/testdata/tests/cases/compiler/regexpReplaceSingleParameterCallback.ts b/tsc/testdata/tests/cases/compiler/regexpReplaceSingleParameterCallback.ts new file mode 100644 index 0000000000000..79ccdf06bf869 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/regexpReplaceSingleParameterCallback.ts @@ -0,0 +1,6 @@ +// @target: es2015 +// @strict: true + +declare const pattern: RegExp; +declare const replace: (value: string) => string; +"".replace(pattern, replace); From 396d27f1e4d99e1ebd60d33e68709771e9671a0a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:48:33 -0700 Subject: [PATCH 115/116] Add historical RegExp constructor match-groups coverage Preserve named-groups access after matching a dynamic pattern constructed without flags. Source: https://redirect.github.com/microsoft/TypeScript/pull/60249#issuecomment-2467177299 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../compiler/regexpConstructorMatchGroups.js | 13 +++++++++++ .../regexpConstructorMatchGroups.symbols | 19 ++++++++++++++++ .../regexpConstructorMatchGroups.types | 22 +++++++++++++++++++ .../compiler/regexpConstructorMatchGroups.ts | 6 +++++ 4 files changed, 60 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.js create mode 100644 tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.types create mode 100644 tsc/testdata/tests/cases/compiler/regexpConstructorMatchGroups.ts diff --git a/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.js b/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.js new file mode 100644 index 0000000000000..e7329ff7929ce --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/regexpConstructorMatchGroups.ts] //// + +//// [regexpConstructorMatchGroups.ts] +declare const pattern: string; +const matches = "".match(new RegExp(pattern)); +if (matches) matches.groups; + + +//// [regexpConstructorMatchGroups.js] +"use strict"; +const matches = "".match(new RegExp(pattern)); +if (matches) + matches.groups; diff --git a/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.symbols b/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.symbols new file mode 100644 index 0000000000000..79c02453734ed --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/regexpConstructorMatchGroups.ts] //// + +=== regexpConstructorMatchGroups.ts === +declare const pattern: string; +>pattern : Symbol(pattern, Decl(regexpConstructorMatchGroups.ts, 0, 13)) + +const matches = "".match(new RegExp(pattern)); +>matches : Symbol(matches, Decl(regexpConstructorMatchGroups.ts, 1, 5)) +>"".match : Symbol(String.match, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>RegExp : Symbol(RegExp, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.regexp.d.ts, --, --)) +>pattern : Symbol(pattern, Decl(regexpConstructorMatchGroups.ts, 0, 13)) + +if (matches) matches.groups; +>matches : Symbol(matches, Decl(regexpConstructorMatchGroups.ts, 1, 5)) +>matches.groups : Symbol(RegExpMatchArray.groups, Decl(lib.es2018.regexp.d.ts, --, --)) +>matches : Symbol(matches, Decl(regexpConstructorMatchGroups.ts, 1, 5)) +>groups : Symbol(RegExpMatchArray.groups, Decl(lib.es2018.regexp.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.types b/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.types new file mode 100644 index 0000000000000..ec6dfa71a2bbf --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpConstructorMatchGroups.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/regexpConstructorMatchGroups.ts] //// + +=== regexpConstructorMatchGroups.ts === +declare const pattern: string; +>pattern : string + +const matches = "".match(new RegExp(pattern)); +>matches : RegExpMatchArray | null +>"".match(new RegExp(pattern)) : RegExpMatchArray | null +>"".match : { (regexp: string | RegExp): RegExpMatchArray | null; (matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null; } +>"" : "" +>match : { (regexp: string | RegExp): RegExpMatchArray | null; (matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null; } +>new RegExp(pattern) : RegExp +>RegExp : RegExpConstructor +>pattern : string + +if (matches) matches.groups; +>matches : RegExpMatchArray | null +>matches.groups : { [key: string]: string; } | undefined +>matches : RegExpMatchArray +>groups : { [key: string]: string; } | undefined + diff --git a/tsc/testdata/tests/cases/compiler/regexpConstructorMatchGroups.ts b/tsc/testdata/tests/cases/compiler/regexpConstructorMatchGroups.ts new file mode 100644 index 0000000000000..4268ecee7d664 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/regexpConstructorMatchGroups.ts @@ -0,0 +1,6 @@ +// @target: es2018 +// @strict: true + +declare const pattern: string; +const matches = "".match(new RegExp(pattern)); +if (matches) matches.groups; From bbc43bfacbbc1be0c70ae3a709d53f467abeafb6 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 16 Oct 2026 13:48:37 -0700 Subject: [PATCH 116/116] Add historical global RegExp match iteration coverage Preserve string elements when iterating whole matches from a dynamic global RegExp. Source: https://redirect.github.com/microsoft/TypeScript/pull/60249#issuecomment-2467177299 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 736819aa-5f3d-4bce-b59b-e63c38aaec88 --- .../regexpGlobalConstructorMatchIteration.js | 21 +++++++++++ ...expGlobalConstructorMatchIteration.symbols | 30 ++++++++++++++++ ...egexpGlobalConstructorMatchIteration.types | 35 +++++++++++++++++++ .../regexpGlobalConstructorMatchIteration.ts | 11 ++++++ 4 files changed, 97 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.js create mode 100644 tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.types create mode 100644 tsc/testdata/tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts diff --git a/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.js b/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.js new file mode 100644 index 0000000000000..fe0eeee29075a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts] //// + +//// [regexpGlobalConstructorMatchIteration.ts] +declare const pattern: string; +declare function consume(value: string): void; +const matches = "".match(new RegExp(pattern, "g")); +if (matches) { + for (const match of matches) { + consume(match); + } +} + + +//// [regexpGlobalConstructorMatchIteration.js] +"use strict"; +const matches = "".match(new RegExp(pattern, "g")); +if (matches) { + for (const match of matches) { + consume(match); + } +} diff --git a/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.symbols b/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.symbols new file mode 100644 index 0000000000000..5c8d472f6656b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.symbols @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts] //// + +=== regexpGlobalConstructorMatchIteration.ts === +declare const pattern: string; +>pattern : Symbol(pattern, Decl(regexpGlobalConstructorMatchIteration.ts, 0, 13)) + +declare function consume(value: string): void; +>consume : Symbol(consume, Decl(regexpGlobalConstructorMatchIteration.ts, 0, 30)) +>value : Symbol(value, Decl(regexpGlobalConstructorMatchIteration.ts, 1, 25)) + +const matches = "".match(new RegExp(pattern, "g")); +>matches : Symbol(matches, Decl(regexpGlobalConstructorMatchIteration.ts, 2, 5)) +>"".match : Symbol(String.match, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>RegExp : Symbol(RegExp, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>pattern : Symbol(pattern, Decl(regexpGlobalConstructorMatchIteration.ts, 0, 13)) + +if (matches) { +>matches : Symbol(matches, Decl(regexpGlobalConstructorMatchIteration.ts, 2, 5)) + + for (const match of matches) { +>match : Symbol(match, Decl(regexpGlobalConstructorMatchIteration.ts, 4, 14)) +>matches : Symbol(matches, Decl(regexpGlobalConstructorMatchIteration.ts, 2, 5)) + + consume(match); +>consume : Symbol(consume, Decl(regexpGlobalConstructorMatchIteration.ts, 0, 30)) +>match : Symbol(match, Decl(regexpGlobalConstructorMatchIteration.ts, 4, 14)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.types b/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.types new file mode 100644 index 0000000000000..ff0892e2ecb34 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/regexpGlobalConstructorMatchIteration.types @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts] //// + +=== regexpGlobalConstructorMatchIteration.ts === +declare const pattern: string; +>pattern : string + +declare function consume(value: string): void; +>consume : (value: string) => void +>value : string + +const matches = "".match(new RegExp(pattern, "g")); +>matches : RegExpMatchArray | null +>"".match(new RegExp(pattern, "g")) : RegExpMatchArray | null +>"".match : { (regexp: string | RegExp): RegExpMatchArray | null; (matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null; } +>"" : "" +>match : { (regexp: string | RegExp): RegExpMatchArray | null; (matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null; } +>new RegExp(pattern, "g") : RegExp +>RegExp : RegExpConstructor +>pattern : string +>"g" : "g" + +if (matches) { +>matches : RegExpMatchArray | null + + for (const match of matches) { +>match : string +>matches : RegExpMatchArray + + consume(match); +>consume(match) : void +>consume : (value: string) => void +>match : string + } +} + diff --git a/tsc/testdata/tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts b/tsc/testdata/tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts new file mode 100644 index 0000000000000..81e0d7c939b7d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/regexpGlobalConstructorMatchIteration.ts @@ -0,0 +1,11 @@ +// @target: es2015 +// @strict: true + +declare const pattern: string; +declare function consume(value: string): void; +const matches = "".match(new RegExp(pattern, "g")); +if (matches) { + for (const match of matches) { + consume(match); + } +}