diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eb8397a18b019..a822b1d6925f1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15941,8 +15941,7 @@ namespace ts { } function maybeTypeParameterReference(node: Node) { - return !(node.kind === SyntaxKind.QualifiedName || - node.parent.kind === SyntaxKind.TypeReference && (node.parent).typeArguments && node === (node.parent).typeName || + return !(node.parent.kind === SyntaxKind.TypeReference && (node.parent as TypeReferenceNode).typeArguments && node === (node.parent as TypeReferenceNode).typeName || node.parent.kind === SyntaxKind.ImportType && (node.parent as ImportTypeNode).typeArguments && node === (node.parent as ImportTypeNode).qualifier); } @@ -15971,7 +15970,10 @@ namespace ts { return true; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - return (!(node as FunctionLikeDeclaration).type && !!(node as FunctionLikeDeclaration).body) || !!forEachChild(node, containsReference); + return !(node as FunctionLikeDeclaration).type && !!(node as FunctionLikeDeclaration).body || + some((node as FunctionLikeDeclaration).typeParameters, containsReference) || + some((node as FunctionLikeDeclaration).parameters, containsReference) || + !!(node as FunctionLikeDeclaration).type && containsReference((node as FunctionLikeDeclaration).type!); } return !!forEachChild(node, containsReference); } diff --git a/tests/baselines/reference/noAsConstNameLookup.js b/tests/baselines/reference/noAsConstNameLookup.js new file mode 100644 index 0000000000000..4b81035daa5b9 --- /dev/null +++ b/tests/baselines/reference/noAsConstNameLookup.js @@ -0,0 +1,70 @@ +//// [noAsConstNameLookup.ts] +// Repros from #44292 + +type Store = { a: 123 } +export type Cleaner = (runner: FeatureRunner) => Promise + +export class FeatureRunner { + private readonly cleaners: Cleaner[] = [] + + async runFeature(): Promise { + const objectWhichShouldBeConst = { + flags: {}, + settings: {}, + } as const; + return objectWhichShouldBeConst + } + + async run(): Promise { + const result = {} + this.cleaners.forEach(c => c(this)) + return result + } +} + +export class C { + f(): void { + let one = 1 as const; + } +} +new C().f(); + + +//// [noAsConstNameLookup.js] +// Repros from #44292 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +export class FeatureRunner { + constructor() { + this.cleaners = []; + } + runFeature() { + return __awaiter(this, void 0, void 0, function* () { + const objectWhichShouldBeConst = { + flags: {}, + settings: {}, + }; + return objectWhichShouldBeConst; + }); + } + run() { + return __awaiter(this, void 0, void 0, function* () { + const result = {}; + this.cleaners.forEach(c => c(this)); + return result; + }); + } +} +export class C { + f() { + let one = 1; + } +} +new C().f(); diff --git a/tests/baselines/reference/noAsConstNameLookup.symbols b/tests/baselines/reference/noAsConstNameLookup.symbols new file mode 100644 index 0000000000000..e2d0a965da48a --- /dev/null +++ b/tests/baselines/reference/noAsConstNameLookup.symbols @@ -0,0 +1,81 @@ +=== tests/cases/compiler/noAsConstNameLookup.ts === +// Repros from #44292 + +type Store = { a: 123 } +>Store : Symbol(Store, Decl(noAsConstNameLookup.ts, 0, 0)) +>a : Symbol(a, Decl(noAsConstNameLookup.ts, 2, 14)) + +export type Cleaner = (runner: FeatureRunner) => Promise +>Cleaner : Symbol(Cleaner, Decl(noAsConstNameLookup.ts, 2, 23)) +>W : Symbol(W, Decl(noAsConstNameLookup.ts, 3, 23)) +>Store : Symbol(Store, Decl(noAsConstNameLookup.ts, 0, 0)) +>runner : Symbol(runner, Decl(noAsConstNameLookup.ts, 3, 40)) +>FeatureRunner : Symbol(FeatureRunner, Decl(noAsConstNameLookup.ts, 3, 81)) +>W : Symbol(W, Decl(noAsConstNameLookup.ts, 3, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export class FeatureRunner { +>FeatureRunner : Symbol(FeatureRunner, Decl(noAsConstNameLookup.ts, 3, 81)) +>W : Symbol(W, Decl(noAsConstNameLookup.ts, 5, 27)) +>Store : Symbol(Store, Decl(noAsConstNameLookup.ts, 0, 0)) + + private readonly cleaners: Cleaner[] = [] +>cleaners : Symbol(FeatureRunner.cleaners, Decl(noAsConstNameLookup.ts, 5, 45)) +>Cleaner : Symbol(Cleaner, Decl(noAsConstNameLookup.ts, 2, 23)) + + async runFeature(): Promise { +>runFeature : Symbol(FeatureRunner.runFeature, Decl(noAsConstNameLookup.ts, 6, 45)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + const objectWhichShouldBeConst = { +>objectWhichShouldBeConst : Symbol(objectWhichShouldBeConst, Decl(noAsConstNameLookup.ts, 9, 13)) + + flags: {}, +>flags : Symbol(flags, Decl(noAsConstNameLookup.ts, 9, 42)) + + settings: {}, +>settings : Symbol(settings, Decl(noAsConstNameLookup.ts, 10, 22)) + + } as const; + return objectWhichShouldBeConst +>objectWhichShouldBeConst : Symbol(objectWhichShouldBeConst, Decl(noAsConstNameLookup.ts, 9, 13)) + } + + async run(): Promise { +>run : Symbol(FeatureRunner.run, Decl(noAsConstNameLookup.ts, 14, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + const result = {} +>result : Symbol(result, Decl(noAsConstNameLookup.ts, 17, 13)) + + this.cleaners.forEach(c => c(this)) +>this.cleaners.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>this.cleaners : Symbol(FeatureRunner.cleaners, Decl(noAsConstNameLookup.ts, 5, 45)) +>this : Symbol(FeatureRunner, Decl(noAsConstNameLookup.ts, 3, 81)) +>cleaners : Symbol(FeatureRunner.cleaners, Decl(noAsConstNameLookup.ts, 5, 45)) +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>c : Symbol(c, Decl(noAsConstNameLookup.ts, 18, 30)) +>c : Symbol(c, Decl(noAsConstNameLookup.ts, 18, 30)) +>this : Symbol(FeatureRunner, Decl(noAsConstNameLookup.ts, 3, 81)) + + return result +>result : Symbol(result, Decl(noAsConstNameLookup.ts, 17, 13)) + } +} + +export class C { +>C : Symbol(C, Decl(noAsConstNameLookup.ts, 21, 1)) +>T : Symbol(T, Decl(noAsConstNameLookup.ts, 23, 15)) + + f(): void { +>f : Symbol(C.f, Decl(noAsConstNameLookup.ts, 23, 19)) + + let one = 1 as const; +>one : Symbol(one, Decl(noAsConstNameLookup.ts, 25, 11)) + } +} +new C().f(); +>new C().f : Symbol(C.f, Decl(noAsConstNameLookup.ts, 23, 19)) +>C : Symbol(C, Decl(noAsConstNameLookup.ts, 21, 1)) +>f : Symbol(C.f, Decl(noAsConstNameLookup.ts, 23, 19)) + diff --git a/tests/baselines/reference/noAsConstNameLookup.types b/tests/baselines/reference/noAsConstNameLookup.types new file mode 100644 index 0000000000000..42a06c8530fb2 --- /dev/null +++ b/tests/baselines/reference/noAsConstNameLookup.types @@ -0,0 +1,83 @@ +=== tests/cases/compiler/noAsConstNameLookup.ts === +// Repros from #44292 + +type Store = { a: 123 } +>Store : Store +>a : 123 + +export type Cleaner = (runner: FeatureRunner) => Promise +>Cleaner : Cleaner +>runner : FeatureRunner + +export class FeatureRunner { +>FeatureRunner : FeatureRunner + + private readonly cleaners: Cleaner[] = [] +>cleaners : Cleaner[] +>[] : never[] + + async runFeature(): Promise { +>runFeature : () => Promise + + const objectWhichShouldBeConst = { +>objectWhichShouldBeConst : { readonly flags: {}; readonly settings: {}; } +>{ flags: {}, settings: {}, } as const : { readonly flags: {}; readonly settings: {}; } +>{ flags: {}, settings: {}, } : { readonly flags: {}; readonly settings: {}; } + + flags: {}, +>flags : {} +>{} : {} + + settings: {}, +>settings : {} +>{} : {} + + } as const; + return objectWhichShouldBeConst +>objectWhichShouldBeConst : { readonly flags: {}; readonly settings: {}; } + } + + async run(): Promise { +>run : () => Promise + + const result = {} +>result : {} +>{} : {} + + this.cleaners.forEach(c => c(this)) +>this.cleaners.forEach(c => c(this)) : void +>this.cleaners.forEach : (callbackfn: (value: Cleaner, index: number, array: Cleaner[]) => void, thisArg?: any) => void +>this.cleaners : Cleaner[] +>this : this +>cleaners : Cleaner[] +>forEach : (callbackfn: (value: Cleaner, index: number, array: Cleaner[]) => void, thisArg?: any) => void +>c => c(this) : (c: Cleaner) => Promise +>c : Cleaner +>c(this) : Promise +>c : Cleaner +>this : this + + return result +>result : {} + } +} + +export class C { +>C : C + + f(): void { +>f : () => void + + let one = 1 as const; +>one : 1 +>1 as const : 1 +>1 : 1 + } +} +new C().f(); +>new C().f() : void +>new C().f : () => void +>new C() : C +>C : typeof C +>f : () => void + diff --git a/tests/cases/compiler/noAsConstNameLookup.ts b/tests/cases/compiler/noAsConstNameLookup.ts new file mode 100644 index 0000000000000..62cc8975dc2bc --- /dev/null +++ b/tests/cases/compiler/noAsConstNameLookup.ts @@ -0,0 +1,32 @@ +// @strict: true +// @target: es2015 + +// Repros from #44292 + +type Store = { a: 123 } +export type Cleaner = (runner: FeatureRunner) => Promise + +export class FeatureRunner { + private readonly cleaners: Cleaner[] = [] + + async runFeature(): Promise { + const objectWhichShouldBeConst = { + flags: {}, + settings: {}, + } as const; + return objectWhichShouldBeConst + } + + async run(): Promise { + const result = {} + this.cleaners.forEach(c => c(this)) + return result + } +} + +export class C { + f(): void { + let one = 1 as const; + } +} +new C().f();