diff --git a/internal/ast/ast.go b/internal/ast/ast.go index b27e133e8c..0173465420 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -9643,9 +9643,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 f7db09f9fc..d237878c9b 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -13848,6 +13848,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) } @@ -14219,6 +14222,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/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/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/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/importTag16.errors.txt b/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt deleted file mode 100644 index 53c5cae41d..0000000000 --- a/testdata/baselines/reference/submodule/conformance/importTag16.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -b.js(1,13): error TS1363: A type-only import can specify a default import or named bindings, but not both. - - -==== a.ts (0 errors) ==== - export default interface Foo {} - export interface I {} - -==== 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 - * @param {I} b - */ - export function foo(a, b) {} - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types b/testdata/baselines/reference/submodule/conformance/jsDeclarationsFunctionClassesCjsExportAssignment.types index fbaba50105..1f12a7c093 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 677dc340b5..1d1480068b 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 fabc218336..6173bb4fd3 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 : import("./mod2").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 : import("./mod2").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/importTag16.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/importTag16.errors.txt.diff deleted file mode 100644 index 560817f64b..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(1,13): error TS1363: A type-only import can specify a default import or named bindings, but not both. -+ -+ -+==== a.ts (0 errors) ==== -+ export default interface Foo {} -+ export interface I {} -+ -+==== 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 -+ * @param {I} b -+ */ -+ export function foo(a, b) {} -+ \ 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 0158bec3cb..f1f24d4676 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 add66d18ea..a80151c396 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 87965f2f76..fdea4946cc 100644 --- a/testdata/baselines/reference/submoduleAccepted/conformance/typedefCrossModule.types.diff +++ b/testdata/baselines/reference/submoduleAccepted/conformance/typedefCrossModule.types.diff @@ -84,7 +84,7 @@ var both2 = both1; ->both2 : import("mod2").Both ->both1 : import("mod1").A -+>both2 : import("./mod2").Both ++>both2 : { type: "a"; x: 1; } | { type: "b"; y: 1; } +>both1 : any /** @type {import('./mod3').Both} */ @@ -92,6 +92,6 @@ ->both3 : import("mod3").Both ->both2 : import("mod2").A +>both3 : { type: "a"; x: 1; } | { type: "b"; y: 1; } -+>both2 : import("./mod2").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 + }