From d007a4afaa0f20be00dfc63c63d2a4cbb6f52345 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 28 May 2025 09:51:02 -0700 Subject: [PATCH 1/3] Ensure nodes have real parents, fix parent race --- internal/ast/ast.go | 7 +- internal/binder/binder.go | 4 +- internal/checker/checker.go | 5 ++ internal/parser/reparser.go | 1 + ...nferenceFromAnnotatedFunctionJs.errors.txt | 39 +++++++++++ ...OnlyInferenceFromAnnotatedFunctionJs.types | 10 +-- ...nsFunctionClassesCjsExportAssignment.types | 18 ++--- .../jsDeclarationsTypeAliases.types | 14 ++-- ...sdocTemplateConstructorFunction.errors.txt | 34 +++++++++ .../jsdocTemplateTagDefault.errors.txt | 36 +++++++++- .../typeTagOnFunctionReferencesGeneric.types | 4 +- .../conformance/typedefCrossModule.types | 4 +- .../conformance/typedefTagWrapping.types | 26 +++---- ...nceFromAnnotatedFunctionJs.errors.txt.diff | 43 ++++++++++++ ...nferenceFromAnnotatedFunctionJs.types.diff | 20 +++++- ...ctionClassesCjsExportAssignment.types.diff | 21 +++--- .../jsDeclarationsTypeAliases.types.diff | 29 ++++++-- ...emplateConstructorFunction.errors.txt.diff | 46 ++++++------- .../jsdocTemplateTagDefault.errors.txt.diff | 68 ++++++++++++++++-- ...eTagOnFunctionReferencesGeneric.types.diff | 15 +++- .../conformance/typedefCrossModule.types.diff | 4 +- .../conformance/typedefTagWrapping.types.diff | 69 ++++++++++++++++++- 22 files changed, 416 insertions(+), 101 deletions(-) create mode 100644 testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt create mode 100644 testdata/baselines/reference/submodule/conformance/jsdocTemplateConstructorFunction.errors.txt create mode 100644 testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt.diff diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 2a4de4ecda..6ff8a22a9b 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -9617,9 +9617,10 @@ func (node *JSDocThisTag) Clone(f NodeFactoryCoercible) *Node { // JSDocImportTag type JSDocImportTag struct { JSDocTagBase - ImportClause *Declaration - ModuleSpecifier *Expression - Attributes *Node + JSImportDeclaration *ImportDeclaration + ImportClause *Declaration + ModuleSpecifier *Expression + Attributes *Node } func (f *NodeFactory) NewJSDocImportTag(tagName *IdentifierNode, importClause *Declaration, moduleSpecifier *Node, attributes *Node, comment *NodeList) *Node { diff --git a/internal/binder/binder.go b/internal/binder/binder.go index 5f18fa716a..8828bf5617 100644 --- a/internal/binder/binder.go +++ b/internal/binder/binder.go @@ -581,7 +581,9 @@ func (b *Binder) bind(node *ast.Node) bool { if node == nil { return false } - node.Parent = b.parent + if node.Parent == nil || node.Parent.Flags&ast.NodeFlagsReparsed != 0 { + node.Parent = b.parent + } saveInStrictMode := b.inStrictMode // Even though in the AST the jsdoc @typedef node belongs to the current node, // its symbol might be in the same scope with the current node's symbol. Consider: diff --git a/internal/checker/checker.go b/internal/checker/checker.go index fb08fd759b..914c89f264 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -13829,6 +13829,9 @@ func (c *Checker) getTargetOfImportSpecifier(node *ast.Node, dontResolveAlias bo } } root := node.Parent.Parent.Parent // ImportDeclaration + if root.Kind == ast.KindJSDocImportTag { + root = root.AsJSDocImportTag().JSImportDeclaration.AsNode() + } if ast.IsBindingElement(node) { root = ast.GetRootDeclaration(node) } @@ -14200,6 +14203,8 @@ func (c *Checker) getModuleSpecifierForImportOrExport(node *ast.Node) *ast.Node func getModuleSpecifierFromNode(node *ast.Node) *ast.Node { switch node.Kind { + case ast.KindJSDocImportTag: + return node.AsJSDocImportTag().JSImportDeclaration.ModuleSpecifier case ast.KindImportDeclaration, ast.KindJSImportDeclaration: return node.AsImportDeclaration().ModuleSpecifier case ast.KindExportDeclaration: diff --git a/internal/parser/reparser.go b/internal/parser/reparser.go index 242609e2a3..f6e32ec8e9 100644 --- a/internal/parser/reparser.go +++ b/internal/parser/reparser.go @@ -98,6 +98,7 @@ func (p *Parser) reparseTags(parent *ast.Node, jsDoc []*ast.Node) { importDeclaration.Loc = core.NewTextRange(tag.Pos(), tag.End()) importDeclaration.Flags = p.contextFlags | ast.NodeFlagsReparsed p.reparseList = append(p.reparseList, importDeclaration) + importTag.JSImportDeclaration = importDeclaration.AsImportDeclaration() // !!! @overload and other unattached tags (@callback et al) support goes here } if !isLast { diff --git a/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt b/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt new file mode 100644 index 0000000000..b119782922 --- /dev/null +++ b/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt @@ -0,0 +1,39 @@ +index.js(2,28): error TS2304: Cannot find name 'B'. +index.js(2,42): error TS2304: Cannot find name 'A'. +index.js(2,48): error TS2304: Cannot find name 'B'. +index.js(2,67): error TS2304: Cannot find name 'B'. + + +==== index.js (4 errors) ==== + /** + * @typedef {{ [K in keyof B]: { fn: (a: A, b: B) => void; thing: B[K]; } }} Funcs + ~ +!!! error TS2304: Cannot find name 'B'. + ~ +!!! error TS2304: Cannot find name 'A'. + ~ +!!! error TS2304: Cannot find name 'B'. + ~ +!!! error TS2304: Cannot find name 'B'. + * @template A + * @template {Record} B + */ + + /** + * @template A + * @template {Record} B + * @param {Funcs} fns + * @returns {[A, B]} + */ + function foo(fns) { + return /** @type {any} */ (null); + } + + const result = foo({ + bar: { + fn: + /** @param {string} a */ + (a) => {}, + thing: "asd", + }, + }); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types b/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types index 1e4bd26212..0a096ac73a 100644 --- a/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types +++ b/testdata/baselines/reference/submodule/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types @@ -14,8 +14,8 @@ * @returns {[A, B]} */ function foo(fns) { ->foo : >(fns: Funcs) => [A, B] ->fns : Funcs +>foo : >(fns: { [x: string]: { fn: (a: A, b: B) => void; thing: B; }; }) => [A, B] +>fns : { [x: string]: { fn: (a: A, b: B) => void; thing: B; }; } return /** @type {any} */ (null); >(null) : any @@ -23,9 +23,9 @@ function foo(fns) { } const result = foo({ ->result : [string, { bar: string; }] ->foo({ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },}) : [string, { bar: string; }] ->foo : >(fns: Funcs) => [A, B] +>result : [unknown, Record] +>foo({ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },}) : [unknown, Record] +>foo : >(fns: { [x: string]: { fn: (a: A, b: B) => void; thing: B; }; }) => [A, B] >{ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },} : { bar: { fn: (a: string) => void; thing: string; }; } bar: { diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types b/testdata/baselines/reference/submodule/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types index 7433c03608..1add768839 100644 --- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types +++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types @@ -30,22 +30,22 @@ module.exports = Timer; * @param {HookHandler} handle */ function Hook(handle) { ->Hook : (handle: HookHandler) => void ->handle : HookHandler +>Hook : (handle: (arg: any) => void) => void +>handle : (arg: any) => void this.handle = handle; ->this.handle = handle : HookHandler +>this.handle = handle : (arg: any) => void >this.handle : any >this : any >handle : any ->handle : HookHandler +>handle : (arg: any) => void } module.exports = Hook; ->module.exports = Hook : (handle: HookHandler) => void ->module.exports : (handle: HookHandler) => void ->module : { Hook: (handle: HookHandler) => void; } ->exports : (handle: HookHandler) => void ->Hook : (handle: HookHandler) => void +>module.exports = Hook : (handle: (arg: any) => void) => void +>module.exports : (handle: (arg: any) => void) => void +>module : { Hook: (handle: (arg: any) => void) => void; } +>exports : (handle: (arg: any) => void) => void +>Hook : (handle: (arg: any) => void) => void === context.js === /** diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsTypeAliases.types b/testdata/baselines/reference/submodule/conformance/jsDeclarationsTypeAliases.types index fc578db558..1e6310b58a 100644 --- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsTypeAliases.types +++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsTypeAliases.types @@ -38,7 +38,7 @@ export {}; // flag file as module * @returns {SomeType} */ function doTheThing(x) { ->doTheThing : (x: number) => SomeType +>doTheThing : (x: number) => number | ExportedThing | LocalThing | { x: string; } >x : number return {x: ""+x}; @@ -56,14 +56,14 @@ class ExportedThing { >"ok" : "ok" } module.exports = { ->module.exports = { doTheThing, ExportedThing,} : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } ->module.exports : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } ->module : { export=: { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; }; } ->exports : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } ->{ doTheThing, ExportedThing,} : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } +>module.exports = { doTheThing, ExportedThing,} : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } +>module.exports : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } +>module : { export=: { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; }; } +>exports : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } +>{ doTheThing, ExportedThing,} : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } doTheThing, ->doTheThing : (x: number) => SomeType +>doTheThing : (x: number) => number | ExportedThing | LocalThing | { x: string; } ExportedThing, >ExportedThing : typeof ExportedThing diff --git a/testdata/baselines/reference/submodule/conformance/jsdocTemplateConstructorFunction.errors.txt b/testdata/baselines/reference/submodule/conformance/jsdocTemplateConstructorFunction.errors.txt new file mode 100644 index 0000000000..7c1013c965 --- /dev/null +++ b/testdata/baselines/reference/submodule/conformance/jsdocTemplateConstructorFunction.errors.txt @@ -0,0 +1,34 @@ +templateTagOnConstructorFunctions.js(3,18): error TS2304: Cannot find name 'U'. +templateTagOnConstructorFunctions.js(3,24): error TS2304: Cannot find name 'U'. + + +==== templateTagOnConstructorFunctions.js (2 errors) ==== + /** + * @template U + * @typedef {(u: U) => U} Id + ~ +!!! error TS2304: Cannot find name 'U'. + ~ +!!! error TS2304: Cannot find name 'U'. + */ + /** + * @param {T} t + * @template T + */ + function Zet(t) { + /** @type {T} */ + this.u + this.t = t + } + /** + * @param {T} v + * @param {Id} id + */ + Zet.prototype.add = function(v, id) { + this.u = v || this.t + return id(this.u) + } + var z = new Zet(1) + z.t = 2 + z.u = false + \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/jsdocTemplateTagDefault.errors.txt b/testdata/baselines/reference/submodule/conformance/jsdocTemplateTagDefault.errors.txt index 3e6ab1d570..ae538f84f5 100644 --- a/testdata/baselines/reference/submodule/conformance/jsdocTemplateTagDefault.errors.txt +++ b/testdata/baselines/reference/submodule/conformance/jsdocTemplateTagDefault.errors.txt @@ -1,13 +1,23 @@ file.js(3,15): error TS2304: Cannot find name 'T'. +file.js(17,17): error TS2304: Cannot find name 'T'. +file.js(18,15): error TS2304: Cannot find name 'T'. +file.js(18,18): error TS2304: Cannot find name 'U'. +file.js(23,15): error TS2304: Cannot find name 'T'. +file.js(28,15): error TS2304: Cannot find name 'T'. file.js(33,14): error TS2706: Required type parameters may not follow optional type parameters. -file.js(38,17): error TS2744: Type parameter defaults can only reference previously declared type parameters. +file.js(34,15): error TS2304: Cannot find name 'T'. +file.js(34,18): error TS2304: Cannot find name 'U'. +file.js(38,17): error TS2304: Cannot find name 'U'. +file.js(39,17): error TS2304: Cannot find name 'T'. +file.js(40,15): error TS2304: Cannot find name 'T'. +file.js(40,18): error TS2304: Cannot find name 'U'. file.js(45,17): error TS2304: Cannot find name 'T'. file.js(53,14): error TS2706: Required type parameters may not follow optional type parameters. file.js(60,17): error TS2304: Cannot find name 'U'. file.js(61,17): error TS2304: Cannot find name 'T'. -==== file.js (7 errors) ==== +==== file.js (17 errors) ==== /** * @template {string | number} [T=string] - ok: defaults are permitted * @typedef {[T]} A @@ -27,17 +37,27 @@ file.js(61,17): error TS2304: Cannot find name 'T'. /** * @template T * @template [U=T] - ok: default can reference earlier type parameter + ~ +!!! error TS2304: Cannot find name 'T'. * @typedef {[T, U]} B + ~ +!!! error TS2304: Cannot find name 'T'. + ~ +!!! error TS2304: Cannot find name 'U'. */ /** * @template {string | number} [T] - error: default requires an `=type` * @typedef {[T]} C + ~ +!!! error TS2304: Cannot find name 'T'. */ /** * @template {string | number} [T=] - error: default requires a `type` * @typedef {[T]} D + ~ +!!! error TS2304: Cannot find name 'T'. */ /** @@ -46,14 +66,24 @@ file.js(61,17): error TS2304: Cannot find name 'T'. ~ !!! error TS2706: Required type parameters may not follow optional type parameters. * @typedef {[T, U]} E + ~ +!!! error TS2304: Cannot find name 'T'. + ~ +!!! error TS2304: Cannot find name 'U'. */ /** * @template [T=U] - error: Type parameter defaults can only reference previously declared type parameters. ~ -!!! error TS2744: Type parameter defaults can only reference previously declared type parameters. +!!! error TS2304: Cannot find name 'U'. * @template [U=T] + ~ +!!! error TS2304: Cannot find name 'T'. * @typedef {[T, U]} G + ~ +!!! error TS2304: Cannot find name 'T'. + ~ +!!! error TS2304: Cannot find name 'U'. */ /** diff --git a/testdata/baselines/reference/submodule/conformance/typeTagOnFunctionReferencesGeneric.types b/testdata/baselines/reference/submodule/conformance/typeTagOnFunctionReferencesGeneric.types index 4b523d5efb..14cfb6a773 100644 --- a/testdata/baselines/reference/submodule/conformance/typeTagOnFunctionReferencesGeneric.types +++ b/testdata/baselines/reference/submodule/conformance/typeTagOnFunctionReferencesGeneric.types @@ -20,7 +20,7 @@ inJs(1); // lints error. Why? /**@type {IFn}*/ const inJsArrow = (j) => { ->inJsArrow : IFn +>inJsArrow : (m: T) => T >(j) => { return j;} : (j: T) => T >j : T @@ -29,6 +29,6 @@ const inJsArrow = (j) => { } inJsArrow(2); // no error gets linted as expected >inJsArrow(2) : 2 ->inJsArrow : IFn +>inJsArrow : (m: T) => T >2 : 2 diff --git a/testdata/baselines/reference/submodule/conformance/typedefCrossModule.types b/testdata/baselines/reference/submodule/conformance/typedefCrossModule.types index f7fd67e21f..97cf0da89f 100644 --- a/testdata/baselines/reference/submodule/conformance/typedefCrossModule.types +++ b/testdata/baselines/reference/submodule/conformance/typedefCrossModule.types @@ -78,13 +78,13 @@ var both1 = { type: 'a', x: 1 }; /** @type {import('./mod2').Both} */ var both2 = both1; ->both2 : Both +>both2 : { type: "a"; x: 1; } | { type: "b"; y: 1; } >both1 : any /** @type {import('./mod3').Both} */ var both3 = both2; >both3 : { type: "a"; x: 1; } | { type: "b"; y: 1; } ->both2 : Both +>both2 : { type: "a"; x: 1; } | { type: "b"; y: 1; } diff --git a/testdata/baselines/reference/submodule/conformance/typedefTagWrapping.types b/testdata/baselines/reference/submodule/conformance/typedefTagWrapping.types index ebd2541cad..83e0ce3072 100644 --- a/testdata/baselines/reference/submodule/conformance/typedefTagWrapping.types +++ b/testdata/baselines/reference/submodule/conformance/typedefTagWrapping.types @@ -39,19 +39,19 @@ function callIt(func, arg) { * @returns {string|number} The return. */ function check(obj) { ->check : (obj: Type2) => string | number ->obj : Type2 +>check : (obj: { num: number; str: string; boo: boolean; }) => string | number +>obj : { num: number; str: string; boo: boolean; } return obj.boo ? obj.num : obj.str; >obj.boo ? obj.num : obj.str : string | number >obj.boo : boolean ->obj : Type2 +>obj : { num: number; str: string; boo: boolean; } >boo : boolean >obj.num : number ->obj : Type2 +>obj : { num: number; str: string; boo: boolean; } >num : number >obj.str : string ->obj : Type2 +>obj : { num: number; str: string; boo: boolean; } >str : string } @@ -136,19 +136,19 @@ function use2(func, bool, str, num) { * @returns {string|number} The return. */ function check5(obj) { ->check5 : (obj: Type5) => string | number ->obj : Type5 +>check5 : (obj: { num: number; str: string; boo: boolean; }) => string | number +>obj : { num: number; str: string; boo: boolean; } return obj.boo ? obj.num : obj.str; >obj.boo ? obj.num : obj.str : string | number >obj.boo : boolean ->obj : Type5 +>obj : { num: number; str: string; boo: boolean; } >boo : boolean >obj.num : number ->obj : Type5 +>obj : { num: number; str: string; boo: boolean; } >num : number >obj.str : string ->obj : Type5 +>obj : { num: number; str: string; boo: boolean; } >str : string } @@ -168,12 +168,12 @@ function check5(obj) { * @returns {*} The return. */ function check6(obj) { ->check6 : (obj: Type6) => any ->obj : Type6 +>check6 : (obj: { foo: any; bar: any; }) => any +>obj : { foo: any; bar: any; } return obj.foo; >obj.foo : any ->obj : Type6 +>obj : { foo: any; bar: any; } >foo : any } diff --git a/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt.diff new file mode 100644 index 0000000000..54d0a0203a --- /dev/null +++ b/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt.diff @@ -0,0 +1,43 @@ +--- old.contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt ++++ new.contravariantOnlyInferenceFromAnnotatedFunctionJs.errors.txt +@@= skipped -0, +0 lines =@@ +- ++index.js(2,28): error TS2304: Cannot find name 'B'. ++index.js(2,42): error TS2304: Cannot find name 'A'. ++index.js(2,48): error TS2304: Cannot find name 'B'. ++index.js(2,67): error TS2304: Cannot find name 'B'. ++ ++ ++==== index.js (4 errors) ==== ++ /** ++ * @typedef {{ [K in keyof B]: { fn: (a: A, b: B) => void; thing: B[K]; } }} Funcs ++ ~ ++!!! error TS2304: Cannot find name 'B'. ++ ~ ++!!! error TS2304: Cannot find name 'A'. ++ ~ ++!!! error TS2304: Cannot find name 'B'. ++ ~ ++!!! error TS2304: Cannot find name 'B'. ++ * @template A ++ * @template {Record} B ++ */ ++ ++ /** ++ * @template A ++ * @template {Record} B ++ * @param {Funcs} fns ++ * @returns {[A, B]} ++ */ ++ function foo(fns) { ++ return /** @type {any} */ (null); ++ } ++ ++ const result = foo({ ++ bar: { ++ fn: ++ /** @param {string} a */ ++ (a) => {}, ++ thing: "asd", ++ }, ++ }); \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types.diff b/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types.diff index aba725b5b1..25edfbd20f 100644 --- a/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.types.diff @@ -1,10 +1,26 @@ --- old.contravariantOnlyInferenceFromAnnotatedFunctionJs.types +++ new.contravariantOnlyInferenceFromAnnotatedFunctionJs.types -@@= skipped -18, +18 lines =@@ +@@= skipped -13, +13 lines =@@ + * @returns {[A, B]} + */ + function foo(fns) { +->foo : >(fns: Funcs) => [A, B] +->fns : Funcs ++>foo : >(fns: { [x: string]: { fn: (a: A, b: B) => void; thing: B; }; }) => [A, B] ++>fns : { [x: string]: { fn: (a: A, b: B) => void; thing: B; }; } return /** @type {any} */ (null); >(null) : any +>null : any } - const result = foo({ \ No newline at end of file + const result = foo({ +->result : [string, { bar: string; }] +->foo({ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },}) : [string, { bar: string; }] +->foo : >(fns: Funcs) => [A, B] ++>result : [unknown, Record] ++>foo({ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },}) : [unknown, Record] ++>foo : >(fns: { [x: string]: { fn: (a: A, b: B) => void; thing: B; }; }) => [A, B] + >{ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },} : { bar: { fn: (a: string) => void; thing: string; }; } + + bar: { \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types.diff index 4b00c4661f..3badc9a8f2 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types.diff @@ -35,16 +35,19 @@ */ function Hook(handle) { ->Hook : typeof Hook -+>Hook : (handle: HookHandler) => void - >handle : HookHandler +->handle : HookHandler ++>Hook : (handle: (arg: any) => void) => void ++>handle : (arg: any) => void this.handle = handle; - >this.handle = handle : HookHandler +->this.handle = handle : HookHandler ++>this.handle = handle : (arg: any) => void >this.handle : any ->this : this +>this : any >handle : any - >handle : HookHandler +->handle : HookHandler ++>handle : (arg: any) => void } module.exports = Hook; ->module.exports = Hook : typeof Hook @@ -52,11 +55,11 @@ ->module : { exports: typeof Hook; } ->exports : typeof Hook ->Hook : typeof Hook -+>module.exports = Hook : (handle: HookHandler) => void -+>module.exports : (handle: HookHandler) => void -+>module : { Hook: (handle: HookHandler) => void; } -+>exports : (handle: HookHandler) => void -+>Hook : (handle: HookHandler) => void ++>module.exports = Hook : (handle: (arg: any) => void) => void ++>module.exports : (handle: (arg: any) => void) => void ++>module : { Hook: (handle: (arg: any) => void) => void; } ++>exports : (handle: (arg: any) => void) => void ++>Hook : (handle: (arg: any) => void) => void === context.js === /** diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsTypeAliases.types.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsTypeAliases.types.diff index 3c98bca2c6..7dafe5a6d0 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsTypeAliases.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsTypeAliases.types.diff @@ -1,6 +1,15 @@ --- old.jsDeclarationsTypeAliases.types +++ new.jsDeclarationsTypeAliases.types -@@= skipped -55, +55 lines =@@ +@@= skipped -37, +37 lines =@@ + * @returns {SomeType} + */ + function doTheThing(x) { +->doTheThing : (x: number) => SomeType ++>doTheThing : (x: number) => number | ExportedThing | LocalThing | { x: string; } + >x : number + + return {x: ""+x}; +@@= skipped -18, +18 lines =@@ >"ok" : "ok" } module.exports = { @@ -8,10 +17,16 @@ ->module.exports : typeof module.exports ->module : { exports: typeof module.exports; } ->exports : typeof module.exports -+>module.exports = { doTheThing, ExportedThing,} : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } -+>module.exports : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } -+>module : { export=: { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; }; } -+>exports : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } - >{ doTheThing, ExportedThing,} : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } +->{ doTheThing, ExportedThing,} : { doTheThing: (x: number) => SomeType; ExportedThing: typeof ExportedThing; } ++>module.exports = { doTheThing, ExportedThing,} : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } ++>module.exports : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } ++>module : { export=: { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; }; } ++>exports : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } ++>{ doTheThing, ExportedThing,} : { doTheThing: (x: number) => number | ExportedThing | LocalThing | { x: string; }; ExportedThing: typeof ExportedThing; } + + doTheThing, +->doTheThing : (x: number) => SomeType ++>doTheThing : (x: number) => number | ExportedThing | LocalThing | { x: string; } - doTheThing, \ No newline at end of file + ExportedThing, + >ExportedThing : typeof ExportedThing \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateConstructorFunction.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateConstructorFunction.errors.txt.diff index fd8c906846..a361c709e1 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateConstructorFunction.errors.txt.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateConstructorFunction.errors.txt.diff @@ -5,31 +5,25 @@ - - -==== templateTagOnConstructorFunctions.js (1 errors) ==== -- /** -- * @template U -- * @typedef {(u: U) => U} Id -- */ -- /** -- * @param {T} t -- * @template T -- */ -- function Zet(t) { -- /** @type {T} */ -- this.u -- this.t = t -- } -- /** -- * @param {T} v -- * @param {Id} id -- */ -- Zet.prototype.add = function(v, id) { -- this.u = v || this.t -- return id(this.u) -- } -- var z = new Zet(1) -- z.t = 2 -- z.u = false ++templateTagOnConstructorFunctions.js(3,18): error TS2304: Cannot find name 'U'. ++templateTagOnConstructorFunctions.js(3,24): error TS2304: Cannot find name 'U'. ++ ++ ++==== templateTagOnConstructorFunctions.js (2 errors) ==== + /** + * @template U + * @typedef {(u: U) => U} Id ++ ~ ++!!! error TS2304: Cannot find name 'U'. ++ ~ ++!!! error TS2304: Cannot find name 'U'. + */ + /** + * @param {T} t +@@= skipped -25, +30 lines =@@ + var z = new Zet(1) + z.t = 2 + z.u = false - ~~~ -!!! error TS2322: Type 'boolean' is not assignable to type 'number'. -- -+ \ No newline at end of file + \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateTagDefault.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateTagDefault.errors.txt.diff index d321f65d3a..1589ca977c 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateTagDefault.errors.txt.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsdocTemplateTagDefault.errors.txt.diff @@ -5,16 +5,30 @@ -file.js(22,34): error TS1005: '=' expected. -file.js(27,35): error TS1110: Type expected. +file.js(3,15): error TS2304: Cannot find name 'T'. ++file.js(17,17): error TS2304: Cannot find name 'T'. ++file.js(18,15): error TS2304: Cannot find name 'T'. ++file.js(18,18): error TS2304: Cannot find name 'U'. ++file.js(23,15): error TS2304: Cannot find name 'T'. ++file.js(28,15): error TS2304: Cannot find name 'T'. file.js(33,14): error TS2706: Required type parameters may not follow optional type parameters. - file.js(38,17): error TS2744: Type parameter defaults can only reference previously declared type parameters. +-file.js(38,17): error TS2744: Type parameter defaults can only reference previously declared type parameters. ++file.js(34,15): error TS2304: Cannot find name 'T'. ++file.js(34,18): error TS2304: Cannot find name 'U'. ++file.js(38,17): error TS2304: Cannot find name 'U'. ++file.js(39,17): error TS2304: Cannot find name 'T'. ++file.js(40,15): error TS2304: Cannot find name 'T'. ++file.js(40,18): error TS2304: Cannot find name 'U'. +file.js(45,17): error TS2304: Cannot find name 'T'. file.js(53,14): error TS2706: Required type parameters may not follow optional type parameters. -file.js(60,17): error TS2744: Type parameter defaults can only reference previously declared type parameters. +- +- +-==== file.js (7 errors) ==== +file.js(60,17): error TS2304: Cannot find name 'U'. +file.js(61,17): error TS2304: Cannot find name 'T'. - - - ==== file.js (7 errors) ==== ++ ++ ++==== file.js (17 errors) ==== /** * @template {string | number} [T=string] - ok: defaults are permitted * @typedef {[T]} A @@ -31,13 +45,26 @@ /** @type {A} */ // ok, `T` is provided for `A` const aString = [""]; /** @type {A} */ // ok, `T` is provided for `A` -@@= skipped -31, +31 lines =@@ +@@= skipped -26, +36 lines =@@ + /** + * @template T + * @template [U=T] - ok: default can reference earlier type parameter ++ ~ ++!!! error TS2304: Cannot find name 'T'. + * @typedef {[T, U]} B ++ ~ ++!!! error TS2304: Cannot find name 'T'. ++ ~ ++!!! error TS2304: Cannot find name 'U'. + */ /** * @template {string | number} [T] - error: default requires an `=type` - ~ -!!! error TS1005: '=' expected. * @typedef {[T]} C ++ ~ ++!!! error TS2304: Cannot find name 'T'. */ /** @@ -45,9 +72,36 @@ - ~ -!!! error TS1110: Type expected. * @typedef {[T]} D ++ ~ ++!!! error TS2304: Cannot find name 'T'. + */ + + /** +@@= skipped -23, +29 lines =@@ + ~ + !!! error TS2706: Required type parameters may not follow optional type parameters. + * @typedef {[T, U]} E ++ ~ ++!!! error TS2304: Cannot find name 'T'. ++ ~ ++!!! error TS2304: Cannot find name 'U'. + */ + + /** + * @template [T=U] - error: Type parameter defaults can only reference previously declared type parameters. + ~ +-!!! error TS2744: Type parameter defaults can only reference previously declared type parameters. ++!!! error TS2304: Cannot find name 'U'. + * @template [U=T] ++ ~ ++!!! error TS2304: Cannot find name 'T'. + * @typedef {[T, U]} G ++ ~ ++!!! error TS2304: Cannot find name 'T'. ++ ~ ++!!! error TS2304: Cannot find name 'U'. */ -@@= skipped -31, +27 lines =@@ /** * @template T * @template [U=T] - ok: default can reference earlier type parameter @@ -56,7 +110,7 @@ * @param {T} a * @param {U} b */ -@@= skipped -18, +20 lines =@@ +@@= skipped -31, +43 lines =@@ /** * @template [T=U] - error: Type parameter defaults can only reference previously declared type parameters. ~ diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/typeTagOnFunctionReferencesGeneric.types.diff b/testdata/baselines/reference/submoduleAccepted/conformance/typeTagOnFunctionReferencesGeneric.types.diff index ed888b6474..86695b08b1 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/typeTagOnFunctionReferencesGeneric.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/typeTagOnFunctionReferencesGeneric.types.diff @@ -20,4 +20,17 @@ +>inJs : (l: any) => any >1 : 1 - /**@type {IFn}*/ \ No newline at end of file + /**@type {IFn}*/ + const inJsArrow = (j) => { +->inJsArrow : IFn ++>inJsArrow : (m: T) => T + >(j) => { return j;} : (j: T) => T + >j : T + +@@= skipped -22, +22 lines =@@ + } + inJsArrow(2); // no error gets linted as expected + >inJsArrow(2) : 2 +->inJsArrow : IFn ++>inJsArrow : (m: T) => T + >2 : 2 diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/typedefCrossModule.types.diff b/testdata/baselines/reference/submoduleAccepted/conformance/typedefCrossModule.types.diff index 51eef02901..fa2d112210 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/typedefCrossModule.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/typedefCrossModule.types.diff @@ -83,7 +83,7 @@ var both2 = both1; ->both2 : import("mod2").Both ->both1 : import("mod1").A -+>both2 : Both ++>both2 : { type: "a"; x: 1; } | { type: "b"; y: 1; } +>both1 : any /** @type {import('./mod3').Both} */ @@ -91,6 +91,6 @@ ->both3 : import("mod3").Both ->both2 : import("mod2").A +>both3 : { type: "a"; x: 1; } | { type: "b"; y: 1; } -+>both2 : Both ++>both2 : { type: "a"; x: 1; } | { type: "b"; y: 1; } diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/typedefTagWrapping.types.diff b/testdata/baselines/reference/submoduleAccepted/conformance/typedefTagWrapping.types.diff index d060dcf35a..6d39738624 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/typedefTagWrapping.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/typedefTagWrapping.types.diff @@ -9,7 +9,32 @@ >func : Type1 >arg : string } -@@= skipped -60, +60 lines =@@ +@@= skipped -20, +20 lines =@@ + * @returns {string|number} The return. + */ + function check(obj) { +->check : (obj: Type2) => string | number +->obj : Type2 ++>check : (obj: { num: number; str: string; boo: boolean; }) => string | number ++>obj : { num: number; str: string; boo: boolean; } + + return obj.boo ? obj.num : obj.str; + >obj.boo ? obj.num : obj.str : string | number + >obj.boo : boolean +->obj : Type2 ++>obj : { num: number; str: string; boo: boolean; } + >boo : boolean + >obj.num : number +->obj : Type2 ++>obj : { num: number; str: string; boo: boolean; } + >num : number + >obj.str : string +->obj : Type2 ++>obj : { num: number; str: string; boo: boolean; } + >str : string + } + +@@= skipped -40, +40 lines =@@ >num : number return func(bool, str, num) @@ -26,4 +51,44 @@ +>func(bool, str, num) : any >func : StringOrNumber2 >bool : boolean - >str : string \ No newline at end of file + >str : string +@@= skipped -25, +25 lines =@@ + * @returns {string|number} The return. + */ + function check5(obj) { +->check5 : (obj: Type5) => string | number +->obj : Type5 ++>check5 : (obj: { num: number; str: string; boo: boolean; }) => string | number ++>obj : { num: number; str: string; boo: boolean; } + + return obj.boo ? obj.num : obj.str; + >obj.boo ? obj.num : obj.str : string | number + >obj.boo : boolean +->obj : Type5 ++>obj : { num: number; str: string; boo: boolean; } + >boo : boolean + >obj.num : number +->obj : Type5 ++>obj : { num: number; str: string; boo: boolean; } + >num : number + >obj.str : string +->obj : Type5 ++>obj : { num: number; str: string; boo: boolean; } + >str : string + } + +@@= skipped -32, +32 lines =@@ + * @returns {*} The return. + */ + function check6(obj) { +->check6 : (obj: Type6) => any +->obj : Type6 ++>check6 : (obj: { foo: any; bar: any; }) => any ++>obj : { foo: any; bar: any; } + + return obj.foo; + >obj.foo : any +->obj : Type6 ++>obj : { foo: any; bar: any; } + >foo : any + } From ad3ab5d310c750b503fe5d5f9ae079c4656d455f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 29 May 2025 09:15:26 -0700 Subject: [PATCH 2/3] =?UTF-8?q?Don=E2=80=99t=20check=20JSDocImportTags=20f?= =?UTF-8?q?or=20type-only=20default=20and=20named=20bindings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/checker/grammarchecks.go | 2 +- .../reference/submodule/conformance/importTag16.errors.txt | 5 +---- .../conformance/importTag16.errors.txt.diff | 5 +---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/internal/checker/grammarchecks.go b/internal/checker/grammarchecks.go index 3a6363e567..da139ed53b 100644 --- a/internal/checker/grammarchecks.go +++ b/internal/checker/grammarchecks.go @@ -2117,7 +2117,7 @@ func (c *Checker) checkGrammarBigIntLiteral(node *ast.BigIntLiteral) bool { } func (c *Checker) checkGrammarImportClause(node *ast.ImportClause) bool { - if node.IsTypeOnly && node.Name() != nil && node.NamedBindings != nil { + if node.Flags&ast.NodeFlagsJSDoc == 0 && node.IsTypeOnly && node.Name() != nil && node.NamedBindings != nil { return c.grammarErrorOnNode(&node.Node, diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both) } if node.IsTypeOnly && node.NamedBindings != nil && node.NamedBindings.Kind == ast.KindNamedImports { diff --git a/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt index bdb72b192c..b4437097f1 100644 --- a/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt +++ b/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt @@ -1,4 +1,3 @@ -b.js(1,13): error TS1363: A type-only import can specify a default import or named bindings, but not both. b.js(5,12): error TS4078: Parameter 'b' of exported function has or is using private name 'I'. @@ -6,10 +5,8 @@ b.js(5,12): error TS4078: Parameter 'b' of exported function has or is using pri export default interface Foo {} export interface I {} -==== b.js (2 errors) ==== +==== b.js (1 errors) ==== /** @import Foo, { I } from "./a" */ - ~~~~~~~~~~ -!!! error TS1363: A type-only import can specify a default import or named bindings, but not both. /** * @param {Foo} a diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff index 232a4a1aa9..7d75ccfd2d 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff @@ -2,7 +2,6 @@ +++ new.importTag16.errors.txt @@= skipped -0, +0 lines =@@ - -+b.js(1,13): error TS1363: A type-only import can specify a default import or named bindings, but not both. +b.js(5,12): error TS4078: Parameter 'b' of exported function has or is using private name 'I'. + + @@ -10,10 +9,8 @@ + export default interface Foo {} + export interface I {} + -+==== b.js (2 errors) ==== ++==== b.js (1 errors) ==== + /** @import Foo, { I } from "./a" */ -+ ~~~~~~~~~~ -+!!! error TS1363: A type-only import can specify a default import or named bindings, but not both. + + /** + * @param {Foo} a From 3551e55676be1b777011a7ff82bb088d6b3dc690 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 29 May 2025 09:32:50 -0700 Subject: [PATCH 3/3] Fix handling of JSDoc import tags in symbol accessibility --- internal/checker/utilities.go | 13 ++++++---- .../importTag15(module=es2015).errors.txt | 5 +--- .../importTag15(module=esnext).errors.txt | 5 +--- .../conformance/importTag16.errors.txt | 18 -------------- .../conformance/importTag18.errors.txt | 20 ---------------- .../conformance/importTag19.errors.txt | 19 --------------- .../conformance/importTag20.errors.txt | 20 ---------------- .../conformance/importTag5.errors.txt | 20 ---------------- ...importTag15(module=es2015).errors.txt.diff | 8 ++----- ...importTag15(module=esnext).errors.txt.diff | 24 ------------------- .../conformance/importTag16.errors.txt.diff | 22 ----------------- .../conformance/importTag18.errors.txt.diff | 24 ------------------- .../conformance/importTag19.errors.txt.diff | 23 ------------------ .../conformance/importTag20.errors.txt.diff | 24 ------------------- .../conformance/importTag5.errors.txt.diff | 24 ------------------- 15 files changed, 13 insertions(+), 256 deletions(-) delete mode 100644 testdata/baselines/reference/submodule/conformance/importTag16.errors.txt delete mode 100644 testdata/baselines/reference/submodule/conformance/importTag18.errors.txt delete mode 100644 testdata/baselines/reference/submodule/conformance/importTag19.errors.txt delete mode 100644 testdata/baselines/reference/submodule/conformance/importTag20.errors.txt delete mode 100644 testdata/baselines/reference/submodule/conformance/importTag5.errors.txt delete mode 100644 testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=esnext).errors.txt.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/conformance/importTag18.errors.txt.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/conformance/importTag19.errors.txt.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/conformance/importTag20.errors.txt.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/conformance/importTag5.errors.txt.diff diff --git a/internal/checker/utilities.go b/internal/checker/utilities.go index 9a6b74e38d..61caddabee 100644 --- a/internal/checker/utilities.go +++ b/internal/checker/utilities.go @@ -1918,18 +1918,23 @@ func containsNonMissingUndefinedType(c *Checker, t *Type) bool { } func getAnyImportSyntax(node *ast.Node) *ast.Node { + var importNode *ast.Node switch node.Kind { case ast.KindImportEqualsDeclaration: - return node + importNode = node case ast.KindImportClause: - return node.Parent + importNode = node.Parent case ast.KindNamespaceImport: - return node.Parent.Parent + importNode = node.Parent.Parent case ast.KindImportSpecifier: - return node.Parent.Parent.Parent + importNode = node.Parent.Parent.Parent default: return nil } + if importNode.Kind == ast.KindJSDocImportTag { + return importNode.AsJSDocImportTag().JSImportDeclaration.AsNode() + } + return importNode } // A reserved member name consists of the byte 0xFE (which is an invalid UTF-8 encoding) followed by one or more diff --git a/testdata/baselines/reference/submodule/conformance/importTag15(module=es2015).errors.txt b/testdata/baselines/reference/submodule/conformance/importTag15(module=es2015).errors.txt index cc7719515e..13a7dedcf2 100644 --- a/testdata/baselines/reference/submodule/conformance/importTag15(module=es2015).errors.txt +++ b/testdata/baselines/reference/submodule/conformance/importTag15(module=es2015).errors.txt @@ -2,13 +2,12 @@ 1.js(1,30): error TS2857: Import attributes cannot be used with type-only imports or exports. 1.js(2,33): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. 1.js(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. -1.js(4,13): error TS4078: Parameter 'a' of exported function has or is using private name 'I'. ==== 0.ts (0 errors) ==== export interface I { } -==== 1.js (5 errors) ==== +==== 1.js (4 errors) ==== /** @import { I } from './0' with { type: "json" } */ ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. @@ -21,7 +20,5 @@ !!! error TS2857: Import attributes cannot be used with type-only imports or exports. /** @param {I} a */ - ~ -!!! error TS4078: Parameter 'a' of exported function has or is using private name 'I'. function f(a) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/importTag15(module=esnext).errors.txt b/testdata/baselines/reference/submodule/conformance/importTag15(module=esnext).errors.txt index 688f0be0c7..3b98c15768 100644 --- a/testdata/baselines/reference/submodule/conformance/importTag15(module=esnext).errors.txt +++ b/testdata/baselines/reference/submodule/conformance/importTag15(module=esnext).errors.txt @@ -1,12 +1,11 @@ 1.js(1,30): error TS2857: Import attributes cannot be used with type-only imports or exports. 1.js(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. -1.js(4,13): error TS4078: Parameter 'a' of exported function has or is using private name 'I'. ==== 0.ts (0 errors) ==== export interface I { } -==== 1.js (3 errors) ==== +==== 1.js (2 errors) ==== /** @import { I } from './0' with { type: "json" } */ ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2857: Import attributes cannot be used with type-only imports or exports. @@ -15,7 +14,5 @@ !!! error TS2857: Import attributes cannot be used with type-only imports or exports. /** @param {I} a */ - ~ -!!! error TS4078: Parameter 'a' of exported function has or is using private name 'I'. function f(a) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt deleted file mode 100644 index b4437097f1..0000000000 --- a/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -b.js(5,12): error TS4078: Parameter 'b' of exported function has or is using private name 'I'. - - -==== a.ts (0 errors) ==== - export default interface Foo {} - export interface I {} - -==== b.js (1 errors) ==== - /** @import Foo, { I } from "./a" */ - - /** - * @param {Foo} a - * @param {I} b - ~ -!!! error TS4078: Parameter 'b' of exported function has or is using private name 'I'. - */ - export function foo(a, b) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/importTag18.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag18.errors.txt deleted file mode 100644 index 83b8c40cae..0000000000 --- a/testdata/baselines/reference/submodule/conformance/importTag18.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -b.js(8,12): error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. - - -==== a.ts (0 errors) ==== - export interface Foo {} - -==== b.js (1 errors) ==== - /** - * @import { - * Foo - * } from "./a" - */ - - /** - * @param {Foo} a - ~~~ -!!! error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. - */ - export function foo(a) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/importTag19.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag19.errors.txt deleted file mode 100644 index e42633ba84..0000000000 --- a/testdata/baselines/reference/submodule/conformance/importTag19.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -b.js(7,12): error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. - - -==== a.ts (0 errors) ==== - export interface Foo {} - -==== b.js (1 errors) ==== - /** - * @import { Foo } - * from "./a" - */ - - /** - * @param {Foo} a - ~~~ -!!! error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. - */ - export function foo(a) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/importTag20.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag20.errors.txt deleted file mode 100644 index d47c2c65f5..0000000000 --- a/testdata/baselines/reference/submodule/conformance/importTag20.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -b.js(8,12): error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. - - -==== a.ts (0 errors) ==== - export interface Foo {} - -==== b.js (1 errors) ==== - /** - * @import - * { Foo - * } from './a' - */ - - /** - * @param {Foo} a - ~~~ -!!! error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. - */ - export function foo(a) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/importTag5.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag5.errors.txt deleted file mode 100644 index 214da0a6b1..0000000000 --- a/testdata/baselines/reference/submodule/conformance/importTag5.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -/foo.js(6,13): error TS4078: Parameter 'foo' of exported function has or is using private name 'Foo'. - - -==== /types.ts (0 errors) ==== - export interface Foo { - a: number; - } - -==== /foo.js (1 errors) ==== - /** - * @import { Foo } from "./types" - */ - - /** - * @param { Foo } foo - ~~~ -!!! error TS4078: Parameter 'foo' of exported function has or is using private name 'Foo'. - */ - function f(foo) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=es2015).errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=es2015).errors.txt.diff index b574d0861b..f2e8b9f411 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=es2015).errors.txt.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=es2015).errors.txt.diff @@ -5,14 +5,13 @@ +1.js(1,30): error TS2857: Import attributes cannot be used with type-only imports or exports. 1.js(2,33): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. +1.js(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. -+1.js(4,13): error TS4078: Parameter 'a' of exported function has or is using private name 'I'. ==== 0.ts (0 errors) ==== export interface I { } -==== 1.js (2 errors) ==== -+==== 1.js (5 errors) ==== ++==== 1.js (4 errors) ==== /** @import { I } from './0' with { type: "json" } */ ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. @@ -25,7 +24,4 @@ +!!! error TS2857: Import attributes cannot be used with type-only imports or exports. /** @param {I} a */ -+ ~ -+!!! error TS4078: Parameter 'a' of exported function has or is using private name 'I'. - function f(a) {} - \ No newline at end of file + function f(a) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=esnext).errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=esnext).errors.txt.diff deleted file mode 100644 index d115376be4..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag15(module=esnext).errors.txt.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- old.importTag15(module=esnext).errors.txt -+++ new.importTag15(module=esnext).errors.txt -@@= skipped -0, +0 lines =@@ - 1.js(1,30): error TS2857: Import attributes cannot be used with type-only imports or exports. - 1.js(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. -+1.js(4,13): error TS4078: Parameter 'a' of exported function has or is using private name 'I'. - - - ==== 0.ts (0 errors) ==== - export interface I { } - --==== 1.js (2 errors) ==== -+==== 1.js (3 errors) ==== - /** @import { I } from './0' with { type: "json" } */ - ~~~~~~~~~~~~~~~~~~~~~ - !!! error TS2857: Import attributes cannot be used with type-only imports or exports. -@@= skipped -13, +14 lines =@@ - !!! error TS2857: Import attributes cannot be used with type-only imports or exports. - - /** @param {I} a */ -+ ~ -+!!! error TS4078: Parameter 'a' of exported function has or is using private name 'I'. - function f(a) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff deleted file mode 100644 index 7d75ccfd2d..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff +++ /dev/null @@ -1,22 +0,0 @@ ---- old.importTag16.errors.txt -+++ new.importTag16.errors.txt -@@= skipped -0, +0 lines =@@ -- -+b.js(5,12): error TS4078: Parameter 'b' of exported function has or is using private name 'I'. -+ -+ -+==== a.ts (0 errors) ==== -+ export default interface Foo {} -+ export interface I {} -+ -+==== b.js (1 errors) ==== -+ /** @import Foo, { I } from "./a" */ -+ -+ /** -+ * @param {Foo} a -+ * @param {I} b -+ ~ -+!!! error TS4078: Parameter 'b' of exported function has or is using private name 'I'. -+ */ -+ export function foo(a, b) {} -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag18.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag18.errors.txt.diff deleted file mode 100644 index f95144b5c2..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag18.errors.txt.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- old.importTag18.errors.txt -+++ new.importTag18.errors.txt -@@= skipped -0, +0 lines =@@ -- -+b.js(8,12): error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. -+ -+ -+==== a.ts (0 errors) ==== -+ export interface Foo {} -+ -+==== b.js (1 errors) ==== -+ /** -+ * @import { -+ * Foo -+ * } from "./a" -+ */ -+ -+ /** -+ * @param {Foo} a -+ ~~~ -+!!! error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. -+ */ -+ export function foo(a) {} -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag19.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag19.errors.txt.diff deleted file mode 100644 index 4191c32641..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag19.errors.txt.diff +++ /dev/null @@ -1,23 +0,0 @@ ---- old.importTag19.errors.txt -+++ new.importTag19.errors.txt -@@= skipped -0, +0 lines =@@ -- -+b.js(7,12): error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. -+ -+ -+==== a.ts (0 errors) ==== -+ export interface Foo {} -+ -+==== b.js (1 errors) ==== -+ /** -+ * @import { Foo } -+ * from "./a" -+ */ -+ -+ /** -+ * @param {Foo} a -+ ~~~ -+!!! error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. -+ */ -+ export function foo(a) {} -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag20.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag20.errors.txt.diff deleted file mode 100644 index afbcfa8af2..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag20.errors.txt.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- old.importTag20.errors.txt -+++ new.importTag20.errors.txt -@@= skipped -0, +0 lines =@@ -- -+b.js(8,12): error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. -+ -+ -+==== a.ts (0 errors) ==== -+ export interface Foo {} -+ -+==== b.js (1 errors) ==== -+ /** -+ * @import -+ * { Foo -+ * } from './a' -+ */ -+ -+ /** -+ * @param {Foo} a -+ ~~~ -+!!! error TS4078: Parameter 'a' of exported function has or is using private name 'Foo'. -+ */ -+ export function foo(a) {} -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/importTag5.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag5.errors.txt.diff deleted file mode 100644 index 8e0eabd94a..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/conformance/importTag5.errors.txt.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- old.importTag5.errors.txt -+++ new.importTag5.errors.txt -@@= skipped -0, +0 lines =@@ -- -+/foo.js(6,13): error TS4078: Parameter 'foo' of exported function has or is using private name 'Foo'. -+ -+ -+==== /types.ts (0 errors) ==== -+ export interface Foo { -+ a: number; -+ } -+ -+==== /foo.js (1 errors) ==== -+ /** -+ * @import { Foo } from "./types" -+ */ -+ -+ /** -+ * @param { Foo } foo -+ ~~~ -+!!! error TS4078: Parameter 'foo' of exported function has or is using private name 'Foo'. -+ */ -+ function f(foo) {} -+ \ No newline at end of file