diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a99513cba1dad..8a275911dfc95 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -29672,8 +29672,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!canCollectSymbolAliasAccessabilityData) { return; } - if (location.flags & NodeFlags.Ambient) { - return; // References within types and declaration files are never going to contribute to retaining a JS import + if (location.flags & NodeFlags.Ambient && !isPropertySignature(location) && !isPropertyDeclaration(location)) { + // References within types and declaration files are never going to contribute to retaining a JS import, + // except for properties (which can be decorated). + return; } switch (hint) { case ReferenceHint.Identifier: diff --git a/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).js b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).js new file mode 100644 index 0000000000000..efef8bf919db4 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).js @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts] //// + +//// [observable.d.ts] +export declare class Observable {} + +//// [index.ts] +import { Observable } from './observable'; + +function whatever(a: any, b: any) {} + +class Test { + @whatever + declare prop: Observable; +} + + +//// [index.js] +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const observable_1 = require("./observable"); +function whatever(a, b) { } +class Test { +} +__decorate([ + whatever, + __metadata("design:type", observable_1.Observable) +], Test.prototype, "prop", void 0); diff --git a/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).symbols b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).symbols new file mode 100644 index 0000000000000..c2c8e48b0c03a --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts] //// + +=== observable.d.ts === +export declare class Observable {} +>Observable : Symbol(Observable, Decl(observable.d.ts, 0, 0)) +>T : Symbol(T, Decl(observable.d.ts, 0, 32)) + +=== index.ts === +import { Observable } from './observable'; +>Observable : Symbol(Observable, Decl(index.ts, 0, 8)) + +function whatever(a: any, b: any) {} +>whatever : Symbol(whatever, Decl(index.ts, 0, 42)) +>a : Symbol(a, Decl(index.ts, 2, 18)) +>b : Symbol(b, Decl(index.ts, 2, 25)) + +class Test { +>Test : Symbol(Test, Decl(index.ts, 2, 36)) + + @whatever +>whatever : Symbol(whatever, Decl(index.ts, 0, 42)) + + declare prop: Observable; +>prop : Symbol(Test.prop, Decl(index.ts, 4, 12)) +>Observable : Symbol(Observable, Decl(index.ts, 0, 8)) +} + diff --git a/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).types b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).types new file mode 100644 index 0000000000000..c19c491c9d6f6 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=commonjs).types @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts] //// + +=== observable.d.ts === +export declare class Observable {} +>Observable : Observable +> : ^^^^^^^^^^^^^ + +=== index.ts === +import { Observable } from './observable'; +>Observable : typeof Observable +> : ^^^^^^^^^^^^^^^^^ + +function whatever(a: any, b: any) {} +>whatever : (a: any, b: any) => void +> : ^ ^^ ^^ ^^ ^^^^^^^^^ +>a : any +>b : any + +class Test { +>Test : Test +> : ^^^^ + + @whatever +>whatever : (a: any, b: any) => void +> : ^ ^^ ^^ ^^ ^^^^^^^^^ + + declare prop: Observable; +>prop : Observable +> : ^^^^^^^^^^^^^^^^^^ +} + diff --git a/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).js b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).js new file mode 100644 index 0000000000000..b0cbf8a1c4f4f --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).js @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts] //// + +//// [observable.d.ts] +export declare class Observable {} + +//// [index.ts] +import { Observable } from './observable'; + +function whatever(a: any, b: any) {} + +class Test { + @whatever + declare prop: Observable; +} + + +//// [index.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +import { Observable } from './observable'; +function whatever(a, b) { } +class Test { +} +__decorate([ + whatever, + __metadata("design:type", Observable) +], Test.prototype, "prop", void 0); diff --git a/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).symbols b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).symbols new file mode 100644 index 0000000000000..c2c8e48b0c03a --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts] //// + +=== observable.d.ts === +export declare class Observable {} +>Observable : Symbol(Observable, Decl(observable.d.ts, 0, 0)) +>T : Symbol(T, Decl(observable.d.ts, 0, 32)) + +=== index.ts === +import { Observable } from './observable'; +>Observable : Symbol(Observable, Decl(index.ts, 0, 8)) + +function whatever(a: any, b: any) {} +>whatever : Symbol(whatever, Decl(index.ts, 0, 42)) +>a : Symbol(a, Decl(index.ts, 2, 18)) +>b : Symbol(b, Decl(index.ts, 2, 25)) + +class Test { +>Test : Symbol(Test, Decl(index.ts, 2, 36)) + + @whatever +>whatever : Symbol(whatever, Decl(index.ts, 0, 42)) + + declare prop: Observable; +>prop : Symbol(Test.prop, Decl(index.ts, 4, 12)) +>Observable : Symbol(Observable, Decl(index.ts, 0, 8)) +} + diff --git a/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).types b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).types new file mode 100644 index 0000000000000..c19c491c9d6f6 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataElidedImportOnDeclare(module=esnext).types @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts] //// + +=== observable.d.ts === +export declare class Observable {} +>Observable : Observable +> : ^^^^^^^^^^^^^ + +=== index.ts === +import { Observable } from './observable'; +>Observable : typeof Observable +> : ^^^^^^^^^^^^^^^^^ + +function whatever(a: any, b: any) {} +>whatever : (a: any, b: any) => void +> : ^ ^^ ^^ ^^ ^^^^^^^^^ +>a : any +>b : any + +class Test { +>Test : Test +> : ^^^^ + + @whatever +>whatever : (a: any, b: any) => void +> : ^ ^^ ^^ ^^ ^^^^^^^^^ + + declare prop: Observable; +>prop : Observable +> : ^^^^^^^^^^^^^^^^^^ +} + diff --git a/tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts b/tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts new file mode 100644 index 0000000000000..fb470b6b520d1 --- /dev/null +++ b/tests/cases/compiler/decoratorMetadataElidedImportOnDeclare.ts @@ -0,0 +1,18 @@ +// @target: es2020 +// @module: commonjs, esnext +// @strict: true +// @experimentalDecorators: true +// @emitDecoratorMetadata: true + +// @filename: observable.d.ts +export declare class Observable {} + +// @filename: index.ts +import { Observable } from './observable'; + +function whatever(a: any, b: any) {} + +class Test { + @whatever + declare prop: Observable; +}