From 8d91da6f56d9dbf0c267e98fa39acba5aa8bef9a Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 6 May 2021 16:52:39 +0200 Subject: [PATCH] feat(core): support TypeScript 4.3 Switches the repository to TypeScript 4.3 and the latest version of tslib. This involves updating the peer dependency ranges on `typescript` for the compiler CLI and for the Bazel package. Tests for new TypeScript features have been added to ensure compatibility with Angular's ngtsc compiler. --- .../dockerbuild/scripts-js/package.json | 4 +- .../dockerbuild/scripts-js/yarn.lock | 16 ++--- aio/package.json | 4 +- aio/yarn.lock | 7 +- integration/BUILD.bazel | 6 ++ integration/typings_test_ts43/include-all.ts | 69 +++++++++++++++++++ integration/typings_test_ts43/package.json | 28 ++++++++ integration/typings_test_ts43/tsconfig.json | 26 +++++++ package.json | 4 +- packages/animations/package.json | 2 +- packages/bazel/package.json | 4 +- packages/common/package.json | 2 +- .../ngcc/src/host/esm2015_host.ts | 22 +++--- .../compiler-cli/ngcc/src/host/esm5_host.ts | 4 +- .../compiler-cli/ngcc/src/host/ngcc_host.ts | 5 +- .../compiler-cli/ngcc/src/host/umd_host.ts | 2 +- .../ngcc/test/execution/helpers.ts | 10 ++- .../tasks/queues/serial_task_queue_spec.ts | 7 +- packages/compiler-cli/package.json | 4 +- .../src/ngtsc/imports/src/find_export.ts | 4 ++ .../src/ngtsc/reflection/src/typescript.ts | 2 +- .../src/ngtsc/scope/src/dependency.ts | 5 +- .../src/ngtsc/typecheck/api/BUILD.bazel | 1 + .../src/ngtsc/typecheck/api/scope.ts | 3 +- .../src/ngtsc/typecheck/api/symbols.ts | 7 +- .../src/ngtsc/typecheck/src/checker.ts | 4 +- .../typecheck/src/template_symbol_builder.ts | 16 +++-- ...ecker__get_symbol_of_template_node_spec.ts | 69 ++++++++++--------- .../src/ngtsc/util/src/typescript.ts | 17 +++++ .../compiler-cli/src/typescript_support.ts | 2 +- .../test/ngtsc/template_typecheck_spec.ts | 30 ++++++++ packages/compiler/package.json | 2 +- packages/core/package.json | 2 +- .../initial-navigation/collector.ts | 3 +- .../relative-link-resolution/collector.ts | 3 +- .../declaration_usage_visitor.ts | 2 +- .../schematics/utils/typescript/imports.ts | 2 +- packages/core/src/util/decorators.ts | 2 +- packages/core/src/view/util.ts | 2 + packages/core/test/di/r3_injector_spec.ts | 2 +- packages/elements/package.json | 2 +- packages/forms/package.json | 2 +- packages/forms/test/validators_spec.ts | 14 ++-- packages/language-service/ivy/completions.ts | 20 +++--- .../language-service/ivy/language_service.ts | 5 +- .../ivy/testing/src/buffer.ts | 7 +- packages/language-service/ivy/ts_plugin.ts | 10 +-- packages/language-service/ivy/ts_utils.ts | 2 +- .../src/typescript_symbols.ts | 3 + .../test/reflector_host_spec.ts | 4 +- .../angular-in-memory-web-api/package.json | 2 +- .../platform-browser-dynamic/package.json | 2 +- packages/platform-browser/package.json | 2 +- .../platform-browser/src/dom/dom_renderer.ts | 5 ++ packages/platform-server/package.json | 2 +- packages/router/package.json | 2 +- packages/service-worker/package.json | 2 +- packages/upgrade/package.json | 2 +- packages/zone.js/lib/common/events.ts | 7 +- packages/zone.js/lib/jasmine/jasmine.ts | 4 +- packages/zone.js/package.json | 4 +- packages/zone.js/test/typings/package.json | 2 +- packages/zone.js/yarn.lock | 10 +-- tools/ts-api-guardian/package.json | 2 +- yarn.lock | 9 ++- 65 files changed, 384 insertions(+), 148 deletions(-) create mode 100644 integration/typings_test_ts43/include-all.ts create mode 100644 integration/typings_test_ts43/package.json create mode 100644 integration/typings_test_ts43/tsconfig.json diff --git a/aio/aio-builds-setup/dockerbuild/scripts-js/package.json b/aio/aio-builds-setup/dockerbuild/scripts-js/package.json index 04ea3861050506..01db85214297fa 100644 --- a/aio/aio-builds-setup/dockerbuild/scripts-js/package.json +++ b/aio/aio-builds-setup/dockerbuild/scripts-js/package.json @@ -33,7 +33,7 @@ "shelljs": "^0.8.4", "source-map-support": "^0.5.19", "tar-stream": "^2.1.3", - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "devDependencies": { "@types/body-parser": "^1.19.0", @@ -49,6 +49,6 @@ "supertest": "^4.0.2", "tslint": "^6.1.3", "tslint-jasmine-noSkipOrFocus": "^1.0.9", - "typescript": "^4.2.4" + "typescript": "^4.3.0-dev.20210510" } } diff --git a/aio/aio-builds-setup/dockerbuild/scripts-js/yarn.lock b/aio/aio-builds-setup/dockerbuild/scripts-js/yarn.lock index c7f8e17e12933b..4e776854b39607 100644 --- a/aio/aio-builds-setup/dockerbuild/scripts-js/yarn.lock +++ b/aio/aio-builds-setup/dockerbuild/scripts-js/yarn.lock @@ -2505,10 +2505,10 @@ tslib@^1.8.1: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" -tslib@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== +tslib@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== tslint-jasmine-noSkipOrFocus@^1.0.9: version "1.0.9" @@ -2563,10 +2563,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +typescript@^4.3.0-dev.20210510: + version "4.3.0-dev.20210510" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.0-dev.20210510.tgz#a50dd4f9a6e616f82cb33148c7f5ee80cc07857b" + integrity sha512-HR21ZkELulLWOHfHIA57/6rD1rkadgjyMp1TVeXQ5v82/rn0V3ROkAnd1elt+Mrjc2pTXcIwom7E/N5RCUUxMg== undefsafe@^2.0.2: version "2.0.2" diff --git a/aio/package.json b/aio/package.json index 21a5031c55146d..cafdcbdcd9d7ca 100644 --- a/aio/package.json +++ b/aio/package.json @@ -99,7 +99,7 @@ "@angular/service-worker": "12.0.1", "@webcomponents/custom-elements": "1.4.3", "rxjs": "^6.6.7", - "tslib": "^2.1.0", + "tslib": "^2.2.0", "zone.js": "~0.11.4" }, "devDependencies": { @@ -168,7 +168,7 @@ "tree-kill": "^1.1.0", "ts-node": "^9.1.1", "tslint": "~6.1.3", - "typescript": "~4.2.4", + "typescript": "~4.3.0-dev.20210510", "uglify-js": "^3.13.3", "unist-util-filter": "^2.0.3", "unist-util-source": "^3.0.0", diff --git a/aio/yarn.lock b/aio/yarn.lock index 169aff4f0f574b..8c516a1206c503 100644 --- a/aio/yarn.lock +++ b/aio/yarn.lock @@ -12184,7 +12184,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@4.2.4, typescript@~4.2.4: +typescript@4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== @@ -12194,6 +12194,11 @@ typescript@~3.2.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== +typescript@~4.3.0-dev.20210510: + version "4.3.0-dev.20210510" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.0-dev.20210510.tgz#a50dd4f9a6e616f82cb33148c7f5ee80cc07857b" + integrity sha512-HR21ZkELulLWOHfHIA57/6rD1rkadgjyMp1TVeXQ5v82/rn0V3ROkAnd1elt+Mrjc2pTXcIwom7E/N5RCUUxMg== + ua-parser-js@^0.7.23: version "0.7.28" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.28.tgz#8ba04e653f35ce210239c64661685bf9121dec31" diff --git a/integration/BUILD.bazel b/integration/BUILD.bazel index 0c3ca12cacd1c2..6c9dfc1da1ca03 100644 --- a/integration/BUILD.bazel +++ b/integration/BUILD.bazel @@ -100,6 +100,12 @@ INTEGRATION_TESTS = { # root @npm//typescript package. "pinned_npm_packages": ["typescript"], }, + "typings_test_ts43": { + # Special case for `typings_test_ts43` test as we want to pin + # `typescript` at version 4.3.x for that test and not link to the + # root @npm//typescript package. + "pinned_npm_packages": ["typescript"], + }, } [ diff --git a/integration/typings_test_ts43/include-all.ts b/integration/typings_test_ts43/include-all.ts new file mode 100644 index 00000000000000..86b57f2789d8dd --- /dev/null +++ b/integration/typings_test_ts43/include-all.ts @@ -0,0 +1,69 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + + + +import * as animations from '@angular/animations'; +import * as animationsBrowser from '@angular/animations/browser'; +import * as animationsBrowserTesting from '@angular/animations/browser/testing'; +import * as common from '@angular/common'; +import * as commonHttp from '@angular/common/http'; +import * as commonTesting from '@angular/common/testing'; +import * as commonHttpTesting from '@angular/common/testing'; +import * as compiler from '@angular/compiler'; +import * as compilerTesting from '@angular/compiler/testing'; +import * as core from '@angular/core'; +import * as coreTesting from '@angular/core/testing'; +import * as elements from '@angular/elements'; +import * as forms from '@angular/forms'; +import * as platformBrowser from '@angular/platform-browser'; +import * as platformBrowserDynamic from '@angular/platform-browser-dynamic'; +import * as platformBrowserDynamicTesting from '@angular/platform-browser-dynamic/testing'; +import * as platformBrowserAnimations from '@angular/platform-browser/animations'; +import * as platformBrowserTesting from '@angular/platform-browser/testing'; +import * as platformServer from '@angular/platform-server'; +import * as platformServerInit from '@angular/platform-server/init'; +import * as platformServerTesting from '@angular/platform-server/testing'; +import * as router from '@angular/router'; +import * as routerTesting from '@angular/router/testing'; +import * as routerUpgrade from '@angular/router/upgrade'; +import * as serviceWorker from '@angular/service-worker'; +import * as upgrade from '@angular/upgrade'; +import * as upgradeStatic from '@angular/upgrade/static'; +import * as upgradeTesting from '@angular/upgrade/static/testing'; + +export default { + animations, + animationsBrowser, + animationsBrowserTesting, + common, + commonTesting, + commonHttp, + commonHttpTesting, + compiler, + compilerTesting, + core, + coreTesting, + elements, + forms, + platformBrowser, + platformBrowserTesting, + platformBrowserDynamic, + platformBrowserDynamicTesting, + platformBrowserAnimations, + platformServer, + platformServerInit, + platformServerTesting, + router, + routerTesting, + routerUpgrade, + serviceWorker, + upgrade, + upgradeStatic, + upgradeTesting, +}; diff --git a/integration/typings_test_ts43/package.json b/integration/typings_test_ts43/package.json new file mode 100644 index 00000000000000..0077bf9457c5fc --- /dev/null +++ b/integration/typings_test_ts43/package.json @@ -0,0 +1,28 @@ +{ + "name": "angular-integration", + "description": "Assert that users with TypeScript 4.3 can type-check an Angular application", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@angular/animations": "file:../../dist/packages-dist/animations", + "@angular/common": "file:../../dist/packages-dist/common", + "@angular/compiler": "file:../../dist/packages-dist/compiler", + "@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli", + "@angular/core": "file:../../dist/packages-dist/core", + "@angular/elements": "file:../../dist/packages-dist/elements", + "@angular/forms": "file:../../dist/packages-dist/forms", + "@angular/platform-browser": "file:../../dist/packages-dist/platform-browser", + "@angular/platform-browser-dynamic": "file:../../dist/packages-dist/platform-browser-dynamic", + "@angular/platform-server": "file:../../dist/packages-dist/platform-server", + "@angular/router": "file:../../dist/packages-dist/router", + "@angular/service-worker": "file:../../dist/packages-dist/service-worker", + "@angular/upgrade": "file:../../dist/packages-dist/upgrade", + "@types/jasmine": "file:../../node_modules/@types/jasmine", + "rxjs": "file:../../node_modules/rxjs", + "typescript": "4.3.0-dev.20210510", + "zone.js": "file:../../dist/zone.js-dist/archive/zone.js.tgz" + }, + "scripts": { + "test": "tsc" + } +} diff --git a/integration/typings_test_ts43/tsconfig.json b/integration/typings_test_ts43/tsconfig.json new file mode 100644 index 00000000000000..30e25c22097341 --- /dev/null +++ b/integration/typings_test_ts43/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "experimentalDecorators": true, + "module": "commonjs", + "moduleResolution": "node", + "outDir": "./dist/out-tsc", + "rootDir": ".", + "target": "es5", + "lib": [ + "es5", + "dom", + "es2015.collection", + "es2015.iterable", + "es2015.promise" + ], + "types": [], + }, + "files": [ + "include-all.ts", + "node_modules/@types/jasmine/index.d.ts" + ] +} diff --git a/package.json b/package.json index 86e7c5be014185..8d946d22a0708e 100644 --- a/package.json +++ b/package.json @@ -151,9 +151,9 @@ "terser": "^4.4.0", "tmp": "0.2.1", "tsickle": "0.38.1", - "tslib": "^2.1.0", + "tslib": "^2.2.0", "tslint": "6.1.3", - "typescript": "~4.2.4", + "typescript": "~4.3.0-dev.20210510", "xhr2": "0.2.1", "yaml": "^1.10.0", "yargs": "^17.0.0" diff --git a/packages/animations/package.json b/packages/animations/package.json index 5efaa5cd577508..e35248991b7b0e 100644 --- a/packages/animations/package.json +++ b/packages/animations/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER" diff --git a/packages/bazel/package.json b/packages/bazel/package.json index ba6acf1adbae28..5623c5e1998daa 100644 --- a/packages/bazel/package.json +++ b/packages/bazel/package.json @@ -26,13 +26,13 @@ "@microsoft/api-extractor": "7.7.11", "shelljs": "0.8.4", "tsickle": "^0.38.0", - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/compiler-cli": "0.0.0-PLACEHOLDER", "@bazel/typescript": ">=1.0.0", "terser": "^4.3.1", - "typescript": ">=4.2.3 <4.3", + "typescript": ">=4.2.3 <4.4", "rollup": ">=1.20.0", "rollup-plugin-commonjs": ">=9.0.0", "rollup-plugin-node-resolve": ">=4.2.0", diff --git a/packages/common/package.json b/packages/common/package.json index e55dd9138021af..6399924577dea4 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -9,7 +9,7 @@ }, "locales": "locales", "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts index c4d7c89cbe1f9b..dde6c3e66d9876 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -11,6 +11,7 @@ import * as ts from 'typescript'; import {absoluteFromSourceFile} from '../../../src/ngtsc/file_system'; import {Logger} from '../../../src/ngtsc/logging'; import {ClassDeclaration, ClassMember, ClassMemberKind, CtorParameter, Declaration, DeclarationNode, Decorator, EnumMember, Import, isConcreteDeclaration, isDecoratorIdentifier, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, reflectObjectLiteral, SpecialDeclarationKind, TypeScriptReflectionHost, TypeValueReference, TypeValueReferenceKind, ValueUnavailableKind} from '../../../src/ngtsc/reflection'; +import {isSymbolWithValueDeclaration, SymbolWithValueDeclaration} from '../../../src/ngtsc/util/src/typescript'; import {isWithinPackage} from '../analysis/util'; import {BundleProgram} from '../packages/bundle_program'; import {findAll, getNameText, hasNameIdentifier, isDefined, stripDollarSuffix} from '../utils'; @@ -213,7 +214,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N // That didn't work so now try getting it from the "inner" declaration. const classSymbol = this.getClassSymbol(clazz); - if (classSymbol === undefined || + if (classSymbol?.implementation.valueDeclaration === undefined || !isNamedDeclaration(classSymbol.implementation.valueDeclaration)) { return null; } @@ -241,7 +242,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N } private getNameFromClassSymbolDeclaration( - classSymbol: NgccClassSymbol, declaration: ts.Declaration): ts.Identifier { + classSymbol: NgccClassSymbol, declaration: ts.Declaration|undefined): ts.Identifier { if (declaration === undefined) { throw new Error( `getInternalNameOfClass() called on a class with an undefined internal declaration. External class name: ${ @@ -721,12 +722,12 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N return undefined; } - let implementationSymbol = declarationSymbol; + let implementationSymbol: ts.Symbol|undefined = declarationSymbol; if (innerDeclaration !== null && isNamedDeclaration(innerDeclaration)) { - implementationSymbol = this.checker.getSymbolAtLocation(innerDeclaration.name) as ClassSymbol; + implementationSymbol = this.checker.getSymbolAtLocation(innerDeclaration.name); } - if (implementationSymbol === undefined) { + if (!isSymbolWithValueDeclaration(implementationSymbol)) { return undefined; } @@ -740,8 +741,9 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N return classSymbol; } - private getAdjacentSymbol(declarationSymbol: ClassSymbol, implementationSymbol: ClassSymbol): - ClassSymbol|undefined { + private getAdjacentSymbol( + declarationSymbol: ClassSymbol, + implementationSymbol: SymbolWithValueDeclaration): SymbolWithValueDeclaration|undefined { if (declarationSymbol === implementationSymbol) { return undefined; } @@ -755,9 +757,9 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N if (adjacentDeclaration === undefined || !isNamedVariableDeclaration(adjacentDeclaration)) { return undefined; } - const adjacentSymbol = - this.checker.getSymbolAtLocation(adjacentDeclaration.name) as ClassSymbol; - if (adjacentSymbol === declarationSymbol || adjacentSymbol === implementationSymbol) { + const adjacentSymbol = this.checker.getSymbolAtLocation(adjacentDeclaration.name); + if (adjacentSymbol === declarationSymbol || adjacentSymbol === implementationSymbol || + !isSymbolWithValueDeclaration(adjacentSymbol)) { return undefined; } return adjacentSymbol; diff --git a/packages/compiler-cli/ngcc/src/host/esm5_host.ts b/packages/compiler-cli/ngcc/src/host/esm5_host.ts index 9cd7c758a8eb65..1fe47c4203344a 100644 --- a/packages/compiler-cli/ngcc/src/host/esm5_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm5_host.ts @@ -292,7 +292,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { const members: ClassMember[] = []; if (propertyDefinition.setter) { members.push({ - node, + node: node!, implementation: propertyDefinition.setter, kind: ClassMemberKind.Setter, type: null, @@ -310,7 +310,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { } if (propertyDefinition.getter) { members.push({ - node, + node: node!, implementation: propertyDefinition.getter, kind: ClassMemberKind.Getter, type: null, diff --git a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts index 3d6423cecc1d6b..f4839c5d0cdf51 100644 --- a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts +++ b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts @@ -8,6 +8,7 @@ import * as ts from 'typescript'; import {ClassDeclaration, Declaration, Decorator, ReflectionHost} from '../../../src/ngtsc/reflection'; +import {SymbolWithValueDeclaration} from '../../../src/ngtsc/util/src/typescript'; export const PRE_R3_MARKER = '__PRE_R3__'; export const POST_R3_MARKER = '__POST_R3__'; @@ -47,13 +48,13 @@ export interface NgccClassSymbol { * inner declaration does not need to satisfy the requirements imposed on a publicly visible class * declaration. */ - implementation: ts.Symbol; + implementation: SymbolWithValueDeclaration; /** * Represents the symbol corresponding to a variable within a class IIFE that may be used to * attach static properties or decorated. */ - adjacent?: ts.Symbol; + adjacent?: SymbolWithValueDeclaration; } /** diff --git a/packages/compiler-cli/ngcc/src/host/umd_host.ts b/packages/compiler-cli/ngcc/src/host/umd_host.ts index 1467c2141e21e1..974ccc8e0d7078 100644 --- a/packages/compiler-cli/ngcc/src/host/umd_host.ts +++ b/packages/compiler-cli/ngcc/src/host/umd_host.ts @@ -421,7 +421,7 @@ export class UmdReflectionHost extends Esm5ReflectionHost { const exportsSymbol = this.checker.getSymbolsInScope(id, ts.SymbolFlags.Variable) .find(symbol => symbol.name === 'exports'); - const node = exportsSymbol !== undefined && + const node = exportsSymbol?.valueDeclaration !== undefined && !ts.isFunctionExpression(exportsSymbol.valueDeclaration.parent) ? // There is a locally defined `exports` variable that is not a function parameter. // So this `exports` identifier must be a local variable and does not represent the module. diff --git a/packages/compiler-cli/ngcc/test/execution/helpers.ts b/packages/compiler-cli/ngcc/test/execution/helpers.ts index f01537a6a0533c..9b89efb933f642 100644 --- a/packages/compiler-cli/ngcc/test/execution/helpers.ts +++ b/packages/compiler-cli/ngcc/test/execution/helpers.ts @@ -7,7 +7,7 @@ */ import {DepGraph} from 'dependency-graph'; import {DtsProcessing, PartiallyOrderedTasks, Task} from '../../src/execution/tasks/api'; -import {EntryPoint} from '../../src/packages/entry_point'; +import {EntryPoint, EntryPointJsonProperty} from '../../src/packages/entry_point'; /** * Create a set of tasks and a graph of their interdependencies. @@ -53,7 +53,13 @@ export function createTasksAndGraph( for (let tIdx = 0; tIdx < tasksPerEntryPointCount; tIdx++) { const processDts = tIdx === 0 ? DtsProcessing.Yes : DtsProcessing.No; - tasks.push({entryPoint, formatProperty: `prop-${tIdx}`, processDts} as Task); + const formatProperty = `prop-${tIdx}` as EntryPointJsonProperty; + tasks.push({ + entryPoint, + formatProperty: formatProperty, + formatPropertiesToMarkAsProcessed: [], + processDts + }); } } diff --git a/packages/compiler-cli/ngcc/test/execution/tasks/queues/serial_task_queue_spec.ts b/packages/compiler-cli/ngcc/test/execution/tasks/queues/serial_task_queue_spec.ts index 85b8b630318520..69598f55bfcc3e 100644 --- a/packages/compiler-cli/ngcc/test/execution/tasks/queues/serial_task_queue_spec.ts +++ b/packages/compiler-cli/ngcc/test/execution/tasks/queues/serial_task_queue_spec.ts @@ -33,7 +33,12 @@ describe('SerialTaskQueue', () => { const entryPoint = {name: `entry-point-${i}`, path: `/path/to/entry/point/${i}`} as EntryPoint; const processDts = i % 2 === 0 ? DtsProcessing.Yes : DtsProcessing.No; - tasks.push({entryPoint: entryPoint, formatProperty: `prop-${i}`, processDts} as Task); + tasks.push({ + entryPoint: entryPoint, + formatProperty: `prop-${i}`, + formatPropertiesToMarkAsProcessed: [], + processDts + } as Task); graph.addNode(entryPoint.path); } const dependencies = computeTaskDependencies(tasks, graph); diff --git a/packages/compiler-cli/package.json b/packages/compiler-cli/package.json index 96704bf62a06aa..7e2d554ac11465 100644 --- a/packages/compiler-cli/package.json +++ b/packages/compiler-cli/package.json @@ -23,12 +23,12 @@ "semver": "^7.0.0", "source-map": "^0.6.1", "sourcemap-codec": "^1.4.8", - "tslib": "^2.1.0", + "tslib": "^2.2.0", "yargs": "^17.0.0" }, "peerDependencies": { "@angular/compiler": "0.0.0-PLACEHOLDER", - "typescript": ">=4.2.3 <4.3" + "typescript": ">=4.2.3 <4.4" }, "repository": { "type": "git", diff --git a/packages/compiler-cli/src/ngtsc/imports/src/find_export.ts b/packages/compiler-cli/src/ngtsc/imports/src/find_export.ts index 3809845f6e0db0..a3467d00cc3017 100644 --- a/packages/compiler-cli/src/ngtsc/imports/src/find_export.ts +++ b/packages/compiler-cli/src/ngtsc/imports/src/find_export.ts @@ -51,6 +51,10 @@ export function findExportedNameOfNode( * `ts.ExportSpecifier`s and need to be unwrapped. */ function symbolDeclaresNode(sym: ts.Symbol, node: ts.Node, checker: ts.TypeChecker): boolean { + if (sym.declarations === undefined) { + return false; + } + return sym.declarations.some(decl => { if (ts.isExportSpecifier(decl)) { const exportedSymbol = checker.getExportSpecifierLocalTargetSymbol(decl); diff --git a/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts index 451d0c9ae3fd8b..b11d8180c3c0ed 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts @@ -248,7 +248,7 @@ export class TypeScriptReflectionHost implements ReflectionHost { return null; } const namespaceSymbol = this.checker.getSymbolAtLocation(namespaceIdentifier); - if (!namespaceSymbol) { + if (!namespaceSymbol || namespaceSymbol.declarations === undefined) { return null; } const declaration = diff --git a/packages/compiler-cli/src/ngtsc/scope/src/dependency.ts b/packages/compiler-cli/src/ngtsc/scope/src/dependency.ts index e278c6e3d71b3f..f682352dd026d7 100644 --- a/packages/compiler-cli/src/ngtsc/scope/src/dependency.ts +++ b/packages/compiler-cli/src/ngtsc/scope/src/dependency.ts @@ -150,9 +150,12 @@ export class MetadataDtsModuleScopeResolver implements DtsModuleScopeResolver { return dirOrPipe; } + // TypeScript incorrectly narrows the type here: + // https://github.com/microsoft/TypeScript/issues/43966. + // TODO: Remove/Update once https://github.com/microsoft/TypeScript/issues/43966 is resolved. return { ...dirOrPipe, ref: ref.cloneWithAlias(alias), - }; + } as T; } } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel b/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel index aa34cc2d9502cc..0ee8e61fcc80d2 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel @@ -13,6 +13,7 @@ ts_library( "//packages/compiler-cli/src/ngtsc/imports", "//packages/compiler-cli/src/ngtsc/metadata", "//packages/compiler-cli/src/ngtsc/reflection", + "//packages/compiler-cli/src/ngtsc/util", "@npm//typescript", ], ) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/scope.ts b/packages/compiler-cli/src/ngtsc/typecheck/api/scope.ts index 6593d0a63b3e88..41dbe32c8bd92f 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/scope.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/scope.ts @@ -8,6 +8,7 @@ import * as ts from 'typescript'; import {ClassDeclaration} from '../../reflection'; +import {SymbolWithValueDeclaration} from '../../util/src/typescript'; /** * Metadata on a directive which is available in the scope of a template. @@ -16,7 +17,7 @@ export interface DirectiveInScope { /** * The `ts.Symbol` for the directive class. */ - tsSymbol: ts.Symbol; + tsSymbol: SymbolWithValueDeclaration; /** * The module which declares the directive. diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts b/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts index 1481d6301c5787..89b0f77aebfa80 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts @@ -10,7 +10,8 @@ import {TmplAstElement, TmplAstReference, TmplAstTemplate, TmplAstVariable} from import * as ts from 'typescript'; import {AbsoluteFsPath} from '../../file_system'; -import {ClassDeclaration} from '../../reflection'; +import {SymbolWithValueDeclaration} from '../../util/src/typescript'; + import {DirectiveInScope} from './scope'; export enum SymbolKind { @@ -303,8 +304,8 @@ export interface ClassSymbol { tsType: ts.Type; /** The `ts.Symbol` for class. */ - tsSymbol: ts.Symbol; + tsSymbol: SymbolWithValueDeclaration; /** The position for the variable declaration for the class instance. */ shimLocation: ShimLocation; -} \ No newline at end of file +} diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts index bcb5960ad30a5b..6a4608dc1b2a7c 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts @@ -17,7 +17,7 @@ import {ProgramDriver, UpdateMode} from '../../program_driver'; import {ClassDeclaration, isNamedClassDeclaration, ReflectionHost} from '../../reflection'; import {ComponentScopeReader, TypeCheckScopeRegistry} from '../../scope'; import {isShim} from '../../shims'; -import {getSourceFileOrNull} from '../../util/src/typescript'; +import {getSourceFileOrNull, isSymbolWithValueDeclaration} from '../../util/src/typescript'; import {DirectiveInScope, ElementSymbol, FullTemplateMapping, GlobalCompletion, OptimizeFor, PipeInScope, ProgramTypeCheckAdapter, ShimLocation, Symbol, TemplateId, TemplateSymbol, TemplateTypeChecker, TypeCheckableDirectiveMeta, TypeCheckingConfig} from '../api'; import {TemplateDiagnostic} from '../diagnostics'; @@ -577,7 +577,7 @@ export class TemplateTypeCheckerImpl implements TemplateTypeChecker { continue; } const tsSymbol = typeChecker.getSymbolAtLocation(dir.ref.node.name); - if (tsSymbol === undefined) { + if (!isSymbolWithValueDeclaration(tsSymbol)) { continue; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts index 904970050205de..7e8c6932406b1c 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts @@ -12,7 +12,7 @@ import * as ts from 'typescript'; import {AbsoluteFsPath} from '../../file_system'; import {ClassDeclaration} from '../../reflection'; import {ComponentScopeReader} from '../../scope'; -import {isAssignment} from '../../util/src/typescript'; +import {isAssignment, isSymbolWithValueDeclaration} from '../../util/src/typescript'; import {BindingSymbol, DirectiveSymbol, DomBindingSymbol, ElementSymbol, ExpressionSymbol, InputBindingSymbol, OutputBindingSymbol, PipeSymbol, ReferenceSymbol, ShimLocation, Symbol, SymbolKind, TemplateSymbol, TsNodeSymbolInfo, TypeCheckableDirectiveMeta, VariableSymbol} from '../api'; import {ExpressionIdentifier, findAllMatchingNodes, findFirstMatchingNode, hasExpressionIdentifier} from './comments'; @@ -119,8 +119,7 @@ export class SymbolBuilder { return nodes .map(node => { const symbol = this.getSymbolOfTsNode(node.parent); - if (symbol === null || symbol.tsSymbol === null || - symbol.tsSymbol.valueDeclaration === undefined || + if (symbol === null || !isSymbolWithValueDeclaration(symbol.tsSymbol) || !ts.isClassDeclaration(symbol.tsSymbol.valueDeclaration)) { return null; } @@ -314,7 +313,8 @@ export class SymbolBuilder { // In either case, `_t1["index"]` or `_t1.index`, `node.expression` is _t1. // The retrieved symbol for _t1 will be the variable declaration. const tsSymbol = this.getTypeChecker().getSymbolAtLocation(node.expression); - if (tsSymbol === undefined || tsSymbol.declarations.length === 0 || selector === null) { + if (tsSymbol?.declarations === undefined || tsSymbol.declarations.length === 0 || + selector === null) { return null; } @@ -329,8 +329,7 @@ export class SymbolBuilder { } const symbol = this.getSymbolOfTsNode(declaration); - if (symbol === null || symbol.tsSymbol === null || - symbol.tsSymbol.valueDeclaration === undefined || + if (symbol === null || !isSymbolWithValueDeclaration(symbol.tsSymbol) || !ts.isClassDeclaration(symbol.tsSymbol.valueDeclaration)) { return null; } @@ -444,7 +443,10 @@ export class SymbolBuilder { } const pipeInstance = this.getSymbolOfTsNode(pipeDeclaration.valueDeclaration); - if (pipeInstance === null || pipeInstance.tsSymbol === null) { + // The instance should never be null, nor should the symbol lack a value declaration. This + // is because the node used to look for the `pipeInstance` symbol info is a value + // declaration of another symbol (i.e. the `pipeDeclaration` symbol). + if (pipeInstance === null || !isSymbolWithValueDeclaration(pipeInstance.tsSymbol)) { return null; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts index 9fec2bbda4f453..429a403f3e95e3 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts @@ -74,8 +74,8 @@ runInEachFileSystem(() => { const {attributes} = getAstElements(templateTypeChecker, cmp)[0]; const symbol = templateTypeChecker.getSymbolOfNode(attributes[0], cmp)!; assertInputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('name'); // Ensure we can go back to the original location using the shim location @@ -91,8 +91,8 @@ runInEachFileSystem(() => { const {attributes} = getAstElements(templateTypeChecker, cmp)[0]; const symbol = templateTypeChecker.getSymbolOfNode(attributes[0], cmp)!; assertInputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('name'); }); }); @@ -303,7 +303,7 @@ runInEachFileSystem(() => { function expectUserSymbol(userSymbol: Symbol) { assertVariableSymbol(userSymbol); expect(userSymbol.tsSymbol!.escapedName).toContain('$implicit'); - expect(userSymbol.tsSymbol!.declarations[0].parent!.getText()) + expect(userSymbol.tsSymbol!.declarations![0].parent!.getText()) .toContain('NgForOfContext'); expect(program.getTypeChecker().typeToString(userSymbol.tsType!)).toEqual('User'); expect((userSymbol).declaration).toEqual(templateNode.variables[0]); @@ -312,7 +312,7 @@ runInEachFileSystem(() => { function expectIndexSymbol(indexSymbol: Symbol) { assertVariableSymbol(indexSymbol); expect(indexSymbol.tsSymbol!.escapedName).toContain('index'); - expect(indexSymbol.tsSymbol!.declarations[0].parent!.getText()) + expect(indexSymbol.tsSymbol!.declarations![0].parent!.getText()) .toContain('NgForOfContext'); expect(program.getTypeChecker().typeToString(indexSymbol.tsType!)).toEqual('number'); expect((indexSymbol).declaration).toEqual(templateNode.variables[1]); @@ -370,7 +370,7 @@ runInEachFileSystem(() => { const symbol = templateTypeChecker.getSymbolOfNode(inputNode, cmp)!; assertExpressionSymbol(symbol); expect(program.getTypeChecker().symbolToString(symbol.tsSymbol!)).toEqual('street'); - expect((symbol.tsSymbol!.declarations[0] as ts.PropertyDeclaration).parent.name!.getText()) + expect((symbol.tsSymbol!.declarations![0] as ts.PropertyDeclaration).parent.name!.getText()) .toEqual('Address'); expect(program.getTypeChecker().typeToString(symbol.tsType)).toEqual('string'); @@ -427,7 +427,7 @@ runInEachFileSystem(() => { assertExpressionSymbol(propReadSymbol); expect(program.getTypeChecker().symbolToString(propReadSymbol.tsSymbol!)) .toEqual('street'); - expect((propReadSymbol.tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((propReadSymbol.tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name!.getText()) .toEqual('Address'); expect(program.getTypeChecker().typeToString(propReadSymbol.tsType)) @@ -441,7 +441,7 @@ runInEachFileSystem(() => { assertExpressionSymbol(methodCallSymbol); expect(program.getTypeChecker().symbolToString(methodCallSymbol.tsSymbol!)) .toEqual('speak'); - expect((methodCallSymbol.tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((methodCallSymbol.tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name!.getText()) .toEqual('Person'); expect(program.getTypeChecker().typeToString(methodCallSymbol.tsType)) @@ -856,7 +856,7 @@ runInEachFileSystem(() => { const inputAbinding = (nodes[0] as TmplAstElement).inputs[0]; const aSymbol = templateTypeChecker.getSymbolOfNode(inputAbinding, cmp)!; assertInputBindingSymbol(aSymbol); - expect((aSymbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((aSymbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .name.getText()) .toEqual('inputA'); }); @@ -892,14 +892,14 @@ runInEachFileSystem(() => { const inputAbinding = (nodes[0] as TmplAstElement).inputs[0]; const aSymbol = templateTypeChecker.getSymbolOfNode(inputAbinding, cmp)!; assertInputBindingSymbol(aSymbol); - expect((aSymbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((aSymbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .name.getText()) .toEqual('inputA'); const inputBbinding = (nodes[0] as TmplAstElement).inputs[1]; const bSymbol = templateTypeChecker.getSymbolOfNode(inputBbinding, cmp)!; assertInputBindingSymbol(bSymbol); - expect((bSymbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((bSymbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .name.getText()) .toEqual('inputB'); }); @@ -953,8 +953,8 @@ runInEachFileSystem(() => { TmplAstBoundAttribute; const symbol = templateTypeChecker.getSymbolOfNode(ngForOfBinding, cmp)!; assertInputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('ngForOf'); }); @@ -1050,10 +1050,10 @@ runInEachFileSystem(() => { const inputAbinding = (nodes[0] as TmplAstElement).inputs[0]; const symbol = templateTypeChecker.getSymbolOfNode(inputAbinding, cmp)!; assertInputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('inputA'); - expect((symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name?.text) .toEqual('TestDir'); }); @@ -1091,10 +1091,10 @@ runInEachFileSystem(() => { const inputAbinding = (nodes[0] as TmplAstElement).inputs[0]; const symbol = templateTypeChecker.getSymbolOfNode(inputAbinding, cmp)!; assertInputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('otherInputA'); - expect((symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name?.text) .toEqual('TestDir'); }); @@ -1142,10 +1142,11 @@ runInEachFileSystem(() => { const symbol = templateTypeChecker.getSymbolOfNode(inputAbinding, cmp)!; assertInputBindingSymbol(symbol); expect(new Set(symbol.bindings.map( - b => (b.tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()))) + b => (b.tsSymbol!.declarations![0] as ts.PropertyDeclaration).name.getText()))) .toEqual(new Set(['inputA', 'otherDirInputA'])); - expect(new Set(symbol.bindings.map( - b => (b.tsSymbol!.declarations[0] as ts.PropertyDeclaration).parent.name?.text))) + expect( + new Set(symbol.bindings.map( + b => (b.tsSymbol!.declarations![0] as ts.PropertyDeclaration).parent.name?.text))) .toEqual(new Set(['TestDir', 'OtherDir'])); }); }); @@ -1186,14 +1187,14 @@ runInEachFileSystem(() => { const outputABinding = (nodes[0] as TmplAstElement).outputs[0]; const aSymbol = templateTypeChecker.getSymbolOfNode(outputABinding, cmp)!; assertOutputBindingSymbol(aSymbol); - expect((aSymbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((aSymbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .name.getText()) .toEqual('outputA'); const outputBBinding = (nodes[0] as TmplAstElement).outputs[1]; const bSymbol = templateTypeChecker.getSymbolOfNode(outputBBinding, cmp)!; assertOutputBindingSymbol(bSymbol); - expect((bSymbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((bSymbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .name.getText()) .toEqual('outputB'); }); @@ -1239,10 +1240,10 @@ runInEachFileSystem(() => { const outputABinding = (nodes[0] as TmplAstElement).outputs[0]; const symbol = templateTypeChecker.getSymbolOfNode(outputABinding, cmp)!; assertOutputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('outputA'); - expect((symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name?.text) .toEqual('TestDir'); }); @@ -1304,10 +1305,10 @@ runInEachFileSystem(() => { const outputABinding = (nodes[0] as TmplAstElement).outputs[0]; const symbol = templateTypeChecker.getSymbolOfNode(outputABinding, cmp)!; assertOutputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('outputA'); - expect((symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name?.text) .toEqual('TestDir'); }); @@ -1353,10 +1354,10 @@ runInEachFileSystem(() => { const outputABinding = (nodes[0] as TmplAstElement).outputs[0]; const symbol = templateTypeChecker.getSymbolOfNode(outputABinding, cmp)!; assertOutputBindingSymbol(symbol); - expect( - (symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration).name.getText()) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) + .name.getText()) .toEqual('ngModelChange'); - expect((symbol.bindings[0].tsSymbol!.declarations[0] as ts.PropertyDeclaration) + expect((symbol.bindings[0].tsSymbol!.declarations![0] as ts.PropertyDeclaration) .parent.name?.text) .toEqual('TestDir'); }); diff --git a/packages/compiler-cli/src/ngtsc/util/src/typescript.ts b/packages/compiler-cli/src/ngtsc/util/src/typescript.ts index 44854f778b48ca..10d7bd36f3dbc3 100644 --- a/packages/compiler-cli/src/ngtsc/util/src/typescript.ts +++ b/packages/compiler-cli/src/ngtsc/util/src/typescript.ts @@ -13,6 +13,23 @@ import * as ts from 'typescript'; import {AbsoluteFsPath, getFileSystem} from '../../file_system'; import {DeclarationNode} from '../../reflection'; +/** + * Type describing a symbol that is guaranteed to have a value declaration. + */ +export type SymbolWithValueDeclaration = ts.Symbol&{ + valueDeclaration: ts.Declaration; + declarations: ts.Declaration[]; +}; + +export function isSymbolWithValueDeclaration(symbol: ts.Symbol|null| + undefined): symbol is SymbolWithValueDeclaration { + // If there is a value declaration set, then the `declarations` property is never undefined. We + // still check for the property to exist as this matches with the type that `symbol` is narrowed + // to. + return symbol != null && symbol.valueDeclaration !== undefined && + symbol.declarations !== undefined; +} + export function isDtsPath(filePath: string): boolean { return D_TS.test(filePath); } diff --git a/packages/compiler-cli/src/typescript_support.ts b/packages/compiler-cli/src/typescript_support.ts index ec058be8d7d477..334c4bd85eba74 100644 --- a/packages/compiler-cli/src/typescript_support.ts +++ b/packages/compiler-cli/src/typescript_support.ts @@ -25,7 +25,7 @@ const MIN_TS_VERSION = '4.2.3'; * Note: this check is disabled in g3, search for * `angularCompilerOptions.disableTypeScriptVersionCheck` config param value in g3. */ -const MAX_TS_VERSION = '4.3.0'; +const MAX_TS_VERSION = '4.4.0'; /** * The currently used version of TypeScript, which can be adjusted for testing purposes using diff --git a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts index 83306ea997e908..3f20648be77178 100644 --- a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts +++ b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts @@ -368,6 +368,36 @@ export declare class AnimationEvent { expect(diags.length).toBe(0); }); + // https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#separate-write-types-on-properties + it('should support separate write types on inputs', () => { + env.tsconfig({strictTemplates: true}); + env.write('test.ts', ` + import {Component, NgModule, Input} from '@angular/core'; + + @Component({ + selector: 'test', + template: '', + }) + export class TestCmp {} + + @Component({template: '', selector: 'target-cmp'}) + export class TargetCmp { + @Input() + get disabled(): boolean { return this._disabled; } + set disabled(value: string|boolean) { this._disabled = value === '' || !!value; } + private _disabled = false; + } + + @NgModule({ + declarations: [TestCmp, TargetCmp], + }) + export class Module {} + `); + const diags = env.driveDiagnostics(); + console.error(diags); + expect(diags.length).toBe(0); + }); + describe('strictInputTypes', () => { beforeEach(() => { env.write('test.ts', ` diff --git a/packages/compiler/package.json b/packages/compiler/package.json index b4ae5bf258d6e8..69f47c8a56f356 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "repository": { "type": "git", diff --git a/packages/core/package.json b/packages/core/package.json index 1f097e39c1b0f4..686489d6e300c4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "rxjs": "^6.5.3", diff --git a/packages/core/schematics/migrations/initial-navigation/collector.ts b/packages/core/schematics/migrations/initial-navigation/collector.ts index 0c29ee7b3abb32..dff8c13166f579 100644 --- a/packages/core/schematics/migrations/initial-navigation/collector.ts +++ b/packages/core/schematics/migrations/initial-navigation/collector.ts @@ -70,7 +70,8 @@ export class InitialNavigationCollector { return null; } - if (symbolForIdentifier.declarations.length === 0) { + if (symbolForIdentifier.declarations === undefined || + symbolForIdentifier.declarations.length === 0) { return null; } diff --git a/packages/core/schematics/migrations/relative-link-resolution/collector.ts b/packages/core/schematics/migrations/relative-link-resolution/collector.ts index ee62dbc4a068b1..50c2d65b6c661c 100644 --- a/packages/core/schematics/migrations/relative-link-resolution/collector.ts +++ b/packages/core/schematics/migrations/relative-link-resolution/collector.ts @@ -52,7 +52,8 @@ export class RelativeLinkResolutionCollector { return null; } - if (symbolForIdentifier.declarations.length === 0) { + if (symbolForIdentifier.declarations === undefined || + symbolForIdentifier.declarations.length === 0) { return null; } diff --git a/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts b/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts index ba01b7cdfaf27e..0a06a6d326151e 100644 --- a/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts +++ b/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts @@ -152,7 +152,7 @@ export class DeclarationUsageVisitor { node: ts.PropertyAccessExpression, checkSetter: boolean, checkGetter: boolean) { const propertySymbol = this._getPropertyAccessSymbol(node); - if (!propertySymbol || !propertySymbol.declarations.length || + if (propertySymbol?.declarations === undefined || propertySymbol.declarations.length === 0 || (propertySymbol.getFlags() & ts.SymbolFlags.Accessor) === 0) { return; } diff --git a/packages/core/schematics/utils/typescript/imports.ts b/packages/core/schematics/utils/typescript/imports.ts index bf33f0a2585d66..1418021d5a7c55 100644 --- a/packages/core/schematics/utils/typescript/imports.ts +++ b/packages/core/schematics/utils/typescript/imports.ts @@ -19,7 +19,7 @@ export function getImportOfIdentifier(typeChecker: ts.TypeChecker, node: ts.Iden null { const symbol = typeChecker.getSymbolAtLocation(node); - if (!symbol || !symbol.declarations.length) { + if (!symbol || symbol.declarations === undefined || !symbol.declarations.length) { return null; } diff --git a/packages/core/src/util/decorators.ts b/packages/core/src/util/decorators.ts index 92d4d0e04ca2aa..896460b8b664d1 100644 --- a/packages/core/src/util/decorators.ts +++ b/packages/core/src/util/decorators.ts @@ -65,7 +65,7 @@ export function makeDecorator( // prevents the property is copied during subclassing. const annotations = cls.hasOwnProperty(ANNOTATIONS) ? (cls as any)[ANNOTATIONS] : - Object.defineProperty(cls, ANNOTATIONS, {value: []})[ANNOTATIONS]; + (Object.defineProperty(cls, ANNOTATIONS, {value: []}) as any)[ANNOTATIONS]; annotations.push(annotationInstance); diff --git a/packages/core/src/view/util.ts b/packages/core/src/view/util.ts index c83b49360cb0a7..a7278bfdabc4d8 100644 --- a/packages/core/src/view/util.ts +++ b/packages/core/src/view/util.ts @@ -233,6 +233,8 @@ export function getParentRenderElement(view: ViewData, renderHost: any, def: Nod (renderParent.element!.componentRendererType!.encapsulation === ViewEncapsulation.ShadowDom || // TODO(FW-2290): remove the `encapsulation === 1` fallback logic in v12. + // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an enum + // value that is not known (but previously was the value for ViewEncapsulation.Native) renderParent.element!.componentRendererType!.encapsulation === 1))) { // only children of non components, or children of components with native encapsulation should // be attached. diff --git a/packages/core/test/di/r3_injector_spec.ts b/packages/core/test/di/r3_injector_spec.ts index 07ade1cd4a9a3a..2a5fa6342bdb15 100644 --- a/packages/core/test/di/r3_injector_spec.ts +++ b/packages/core/test/di/r3_injector_spec.ts @@ -64,7 +64,7 @@ describe('InjectorDef-based createInjector()', () => { providedIn: null, // ChildService is derived from ServiceWithDep, so the factory function here must do the right // thing and create an instance of the requested type if one is given. - factory: (t?: typeof ServiceWithDep) => new(t || ServiceWithDep)(ɵɵinject(Service)), + factory: (t?: any) => new(t || ServiceWithDep)(ɵɵinject(Service)), }); } diff --git a/packages/elements/package.json b/packages/elements/package.json index 62b850930451d6..8acf3c302f31f3 100644 --- a/packages/elements/package.json +++ b/packages/elements/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/forms/package.json b/packages/forms/package.json index 26cb0c16857a21..32e74c46328952 100644 --- a/packages/forms/package.json +++ b/packages/forms/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/forms/test/validators_spec.ts b/packages/forms/test/validators_spec.ts index db5d5262d5ba7b..a28748f7093712 100644 --- a/packages/forms/test/validators_spec.ts +++ b/packages/forms/test/validators_spec.ts @@ -403,7 +403,7 @@ describe('Validators', () => { const v = Validators.composeAsync( [promiseValidator({'one': true}), promiseValidator({'two': true})])!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null = null; (v(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors); @@ -417,7 +417,7 @@ describe('Validators', () => { [new AsyncValidatorDirective('expected', {'one': true})]); const validatorFn = Validators.composeAsync(normalizedValidators)!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null = null; (validatorFn(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors); @@ -441,7 +441,7 @@ describe('Validators', () => { it('should ignore nulls', fakeAsync(() => { const v = Validators.composeAsync([promiseValidator({'one': true}), null!])!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null = null; (v(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors); @@ -467,7 +467,7 @@ describe('Validators', () => { const v = Validators.composeAsync( [observableValidator({'one': true}), observableValidator({'two': true})])!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null = null; (v(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors); @@ -480,7 +480,7 @@ describe('Validators', () => { [new AsyncValidatorDirective('expected', {'one': true})]); const validatorFn = Validators.composeAsync(normalizedValidators)!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null = null; (validatorFn(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors)!; @@ -502,7 +502,7 @@ describe('Validators', () => { it('should ignore nulls', () => { const v = Validators.composeAsync([observableValidator({'one': true}), null!])!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null = null; (v(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors); @@ -520,7 +520,7 @@ describe('Validators', () => { const v = Validators.composeAsync( [getTimerObs(100, {one: true}), getTimerObs(200, {two: true})])!; - let errorMap: {[key: string]: any}|null = undefined!; + let errorMap: {[key: string]: any}|null|undefined = undefined; (v(new FormControl('invalid')) as Observable) .pipe(first()) .subscribe((errors: {[key: string]: any}|null) => errorMap = errors); diff --git a/packages/language-service/ivy/completions.ts b/packages/language-service/ivy/completions.ts index 84f89938f275d4..2b72fefc833902 100644 --- a/packages/language-service/ivy/completions.ts +++ b/packages/language-service/ivy/completions.ts @@ -82,9 +82,11 @@ export class CompletionBuilder { */ getCompletionEntryDetails( entryName: string, formatOptions: ts.FormatCodeOptions|ts.FormatCodeSettings|undefined, - preferences: ts.UserPreferences|undefined): ts.CompletionEntryDetails|undefined { + preferences: ts.UserPreferences|undefined, + data: ts.CompletionEntryData|undefined): ts.CompletionEntryDetails|undefined { if (this.isPropertyExpressionCompletion()) { - return this.getPropertyExpressionCompletionDetails(entryName, formatOptions, preferences); + return this.getPropertyExpressionCompletionDetails( + entryName, formatOptions, preferences, data); } else if (this.isElementTagCompletion()) { return this.getElementTagCompletionDetails(entryName); } else if (this.isElementAttributeCompletion()) { @@ -167,12 +169,13 @@ export class CompletionBuilder { private getPropertyExpressionCompletionDetails( this: PropertyExpressionCompletionBuilder, entryName: string, formatOptions: ts.FormatCodeOptions|ts.FormatCodeSettings|undefined, - preferences: ts.UserPreferences|undefined): ts.CompletionEntryDetails|undefined { + preferences: ts.UserPreferences|undefined, + data: ts.CompletionEntryData|undefined): ts.CompletionEntryDetails|undefined { let details: ts.CompletionEntryDetails|undefined = undefined; if (this.node instanceof EmptyExpr || this.node instanceof BoundEvent || this.node.receiver instanceof ImplicitReceiver) { - details = - this.getGlobalPropertyExpressionCompletionDetails(entryName, formatOptions, preferences); + details = this.getGlobalPropertyExpressionCompletionDetails( + entryName, formatOptions, preferences, data); } else { const location = this.compiler.getTemplateTypeChecker().getExpressionCompletionLocation( this.node, this.component); @@ -181,7 +184,7 @@ export class CompletionBuilder { } details = this.tsLS.getCompletionEntryDetails( location.shimPath, location.positionInShimFile, entryName, formatOptions, - /* source */ undefined, preferences); + /* source */ undefined, preferences, data); } if (details !== undefined) { details.displayParts = filterAliasImports(details.displayParts); @@ -292,7 +295,8 @@ export class CompletionBuilder { private getGlobalPropertyExpressionCompletionDetails( this: PropertyExpressionCompletionBuilder, entryName: string, formatOptions: ts.FormatCodeOptions|ts.FormatCodeSettings|undefined, - preferences: ts.UserPreferences|undefined): ts.CompletionEntryDetails|undefined { + preferences: ts.UserPreferences|undefined, + data: ts.CompletionEntryData|undefined): ts.CompletionEntryDetails|undefined { const completions = this.templateTypeChecker.getGlobalCompletions(this.template, this.component, this.node); if (completions === null) { @@ -323,7 +327,7 @@ export class CompletionBuilder { } else { return this.tsLS.getCompletionEntryDetails( componentContext.shimPath, componentContext.positionInShimFile, entryName, formatOptions, - /* source */ undefined, preferences); + /* source */ undefined, preferences, data); } } diff --git a/packages/language-service/ivy/language_service.ts b/packages/language-service/ivy/language_service.ts index 320c98e7a54b87..4bf096f5c796a6 100644 --- a/packages/language-service/ivy/language_service.ts +++ b/packages/language-service/ivy/language_service.ts @@ -244,7 +244,8 @@ export class LanguageService { getCompletionEntryDetails( fileName: string, position: number, entryName: string, formatOptions: ts.FormatCodeOptions|ts.FormatCodeSettings|undefined, - preferences: ts.UserPreferences|undefined): ts.CompletionEntryDetails|undefined { + preferences: ts.UserPreferences|undefined, + data: ts.CompletionEntryData|undefined): ts.CompletionEntryDetails|undefined { return this.withCompilerAndPerfTracing(PerfPhase.LsCompletions, (compiler) => { if (!isTemplateContext(compiler.getCurrentProgram(), fileName, position)) { return undefined; @@ -254,7 +255,7 @@ export class LanguageService { if (builder === null) { return undefined; } - return builder.getCompletionEntryDetails(entryName, formatOptions, preferences); + return builder.getCompletionEntryDetails(entryName, formatOptions, preferences, data); }); } diff --git a/packages/language-service/ivy/testing/src/buffer.ts b/packages/language-service/ivy/testing/src/buffer.ts index 78453739ee108d..4069e2169cfb17 100644 --- a/packages/language-service/ivy/testing/src/buffer.ts +++ b/packages/language-service/ivy/testing/src/buffer.ts @@ -70,9 +70,10 @@ export class OpenBuffer { getCompletionEntryDetails( entryName: string, formatOptions?: ts.FormatCodeOptions|ts.FormatCodeSettings, - preferences?: ts.UserPreferences): ts.CompletionEntryDetails|undefined { + preferences?: ts.UserPreferences, data?: ts.CompletionEntryData): ts.CompletionEntryDetails + |undefined { return this.ngLS.getCompletionEntryDetails( - this.scriptInfo.fileName, this._cursor, entryName, formatOptions, preferences); + this.scriptInfo.fileName, this._cursor, entryName, formatOptions, preferences, data); } getTcb() { @@ -118,4 +119,4 @@ function extractCursorInfo(textWithCursor: string): {cursor: number, text: strin cursor, text: textWithCursor.substr(0, cursor) + textWithCursor.substr(cursor + 1), }; -} \ No newline at end of file +} diff --git a/packages/language-service/ivy/ts_plugin.ts b/packages/language-service/ivy/ts_plugin.ts index e8c6c9084a2932..e564633a8e9c1e 100644 --- a/packages/language-service/ivy/ts_plugin.ts +++ b/packages/language-service/ivy/ts_plugin.ts @@ -95,15 +95,17 @@ export function create(info: ts.server.PluginCreateInfo): NgLanguageService { function getCompletionEntryDetails( fileName: string, position: number, entryName: string, formatOptions: ts.FormatCodeOptions|ts.FormatCodeSettings|undefined, source: string|undefined, - preferences: ts.UserPreferences|undefined): ts.CompletionEntryDetails|undefined { + preferences: ts.UserPreferences|undefined, + data: ts.CompletionEntryData|undefined): ts.CompletionEntryDetails|undefined { if (angularOnly) { return ngLS.getCompletionEntryDetails( - fileName, position, entryName, formatOptions, preferences); + fileName, position, entryName, formatOptions, preferences, data); } else { // If TS could answer the query, then return that result. Otherwise, return from Angular LS. return tsLS.getCompletionEntryDetails( - fileName, position, entryName, formatOptions, source, preferences) ?? - ngLS.getCompletionEntryDetails(fileName, position, entryName, formatOptions, preferences); + fileName, position, entryName, formatOptions, source, preferences, data) ?? + ngLS.getCompletionEntryDetails( + fileName, position, entryName, formatOptions, preferences, data); } } diff --git a/packages/language-service/ivy/ts_utils.ts b/packages/language-service/ivy/ts_utils.ts index 688535247c6b6e..33c9b80acac59d 100644 --- a/packages/language-service/ivy/ts_utils.ts +++ b/packages/language-service/ivy/ts_utils.ts @@ -88,7 +88,7 @@ export function collectMemberMethods( const members: ts.MethodDeclaration[] = []; const apparentProps = typeChecker.getTypeAtLocation(clazz).getApparentProperties(); for (const prop of apparentProps) { - if (ts.isMethodDeclaration(prop.valueDeclaration) && prop.valueDeclaration) { + if (prop.valueDeclaration && ts.isMethodDeclaration(prop.valueDeclaration)) { members.push(prop.valueDeclaration); } } diff --git a/packages/language-service/src/typescript_symbols.ts b/packages/language-service/src/typescript_symbols.ts index 4412a1e5ac0cc6..7d108b1a170983 100644 --- a/packages/language-service/src/typescript_symbols.ts +++ b/packages/language-service/src/typescript_symbols.ts @@ -242,6 +242,9 @@ function selectSignature(type: ts.Type, context: TypeContext, types: Symbol[]): function allParameterTypesMatch(signature: ts.Signature) { const tc = context.checker; return signature.getParameters().every((parameter: ts.Symbol, i: number) => { + if (parameter.valueDeclaration === undefined) { + return false; + } const type = tc.getTypeOfSymbolAtLocation(parameter, parameter.valueDeclaration); return type === passedInTypes[i]; }); diff --git a/packages/language-service/test/reflector_host_spec.ts b/packages/language-service/test/reflector_host_spec.ts index efc682f01104f6..75f8ab964ba601 100644 --- a/packages/language-service/test/reflector_host_spec.ts +++ b/packages/language-service/test/reflector_host_spec.ts @@ -59,8 +59,8 @@ describe('reflector_host_spec', () => { // This resolves all Angular directives in the project. ngLSHost.getAnalyzedModules(); const secondCount = spy.calls.count(); - expect(secondCount).toBeGreaterThan(500); - expect(secondCount).toBeLessThan(600); + expect(secondCount).toBeGreaterThan(400); + expect(secondCount).toBeLessThan(500); spy.calls.reset(); // Third count is due to recompution after the program changes. diff --git a/packages/misc/angular-in-memory-web-api/package.json b/packages/misc/angular-in-memory-web-api/package.json index e9cd4e9ed98557..796d9da10ebd82 100644 --- a/packages/misc/angular-in-memory-web-api/package.json +++ b/packages/misc/angular-in-memory-web-api/package.json @@ -10,7 +10,7 @@ "rxjs": "^6.5.3" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "repository": { "type": "git", diff --git a/packages/platform-browser-dynamic/package.json b/packages/platform-browser-dynamic/package.json index 9299647452a3fa..b22f95333a0584 100644 --- a/packages/platform-browser-dynamic/package.json +++ b/packages/platform-browser-dynamic/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/platform-browser/package.json b/packages/platform-browser/package.json index 21af79216e8af0..484a21311c8f95 100644 --- a/packages/platform-browser/package.json +++ b/packages/platform-browser/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/animations": "0.0.0-PLACEHOLDER", diff --git a/packages/platform-browser/src/dom/dom_renderer.ts b/packages/platform-browser/src/dom/dom_renderer.ts index b9f8e66cf40c1e..31f85be2cd5862 100644 --- a/packages/platform-browser/src/dom/dom_renderer.ts +++ b/packages/platform-browser/src/dom/dom_renderer.ts @@ -102,10 +102,15 @@ export class DomRendererFactory2 implements RendererFactory2 { (renderer).applyToHost(element); return renderer; } + // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an enum + // value that is not known (but previously was the value for ViewEncapsulation.Native) case 1: case ViewEncapsulation.ShadowDom: // TODO(FW-2290): remove the `case 1:` fallback logic and the warning in v12. if ((typeof ngDevMode === 'undefined' || ngDevMode) && + // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an + // enum value that is not known (but previously was the value for + // ViewEncapsulation.Native) !hasLoggedNativeEncapsulationWarning && type.encapsulation === 1) { hasLoggedNativeEncapsulationWarning = true; console.warn( diff --git a/packages/platform-server/package.json b/packages/platform-server/package.json index d81094f9b45fb4..da78e3deea3790 100644 --- a/packages/platform-server/package.json +++ b/packages/platform-server/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "domino": "^2.1.2", - "tslib": "^2.1.0", + "tslib": "^2.2.0", "xhr2": "^0.2.0" }, "repository": { diff --git a/packages/router/package.json b/packages/router/package.json index 1db4a35694be9d..4e81b6b702af95 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -21,7 +21,7 @@ }, "homepage": "https://github.com/angular/angular/tree/master/packages/router", "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/service-worker/package.json b/packages/service-worker/package.json index 05921399e48ddb..10fb4c810da607 100644 --- a/packages/service-worker/package.json +++ b/packages/service-worker/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/upgrade/package.json b/packages/upgrade/package.json index bee0492994aa7b..785857406a282d 100644 --- a/packages/upgrade/package.json +++ b/packages/upgrade/package.json @@ -8,7 +8,7 @@ "node": "^12.14.1 || ^14.0.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "peerDependencies": { "@angular/core": "0.0.0-PLACEHOLDER", diff --git a/packages/zone.js/lib/common/events.ts b/packages/zone.js/lib/common/events.ts index d96100fb2ae00c..0cd86f9b92f111 100644 --- a/packages/zone.js/lib/common/events.ts +++ b/packages/zone.js/lib/common/events.ts @@ -28,8 +28,11 @@ if (typeof window !== 'undefined') { passiveSupported = true; } }); - window.addEventListener('test', options, options); - window.removeEventListener('test', options, options); + // Note: We pass the `options` object as the event handler too. This is not compatible with the + // signature of `addEventListener` or `removeEventListener` but enables us to remove the handler + // without an actual handler. + window.addEventListener('test', options as any, options); + window.removeEventListener('test', options as any, options); } catch (err) { passiveSupported = false; } diff --git a/packages/zone.js/lib/jasmine/jasmine.ts b/packages/zone.js/lib/jasmine/jasmine.ts index ff76d4a9753121..cbdd2f8d372255 100644 --- a/packages/zone.js/lib/jasmine/jasmine.ts +++ b/packages/zone.js/lib/jasmine/jasmine.ts @@ -163,9 +163,9 @@ Zone.__load_patch('jasmine', (global: any, Zone: ZoneType, api: _ZonePrivate) => let spyObj: any; if (propertyNames) { const defineProperty = Object.defineProperty; - Object.defineProperty = function(obj: any, p: string, attributes: any) { + Object.defineProperty = function(obj: T, p: PropertyKey, attributes: any) { return defineProperty.call( - this, obj, p, {...attributes, configurable: true, enumerable: true}); + this, obj, p, {...attributes, configurable: true, enumerable: true}) as T; }; try { spyObj = originalCreateSpyObj.apply(this, args); diff --git a/packages/zone.js/package.json b/packages/zone.js/package.json index 7617743ccb4fb3..b2cff671b31b24 100644 --- a/packages/zone.js/package.json +++ b/packages/zone.js/package.json @@ -8,7 +8,7 @@ "fesm2015": "./fesm2015/zone.js", "typings": "./zone.d.ts", "dependencies": { - "tslib": "^2.1.0" + "tslib": "^2.2.0" }, "devDependencies": { "@externs/nodejs": "^1.5.0", @@ -19,7 +19,7 @@ "mocha": "^8.0.0", "mock-require": "3.0.3", "promises-aplus-tests": "^2.1.2", - "typescript": "4.2.4" + "typescript": "4.3.0-dev.20210510" }, "scripts": { "closuretest": "./scripts/closure/closure_compiler.sh", diff --git a/packages/zone.js/test/typings/package.json b/packages/zone.js/test/typings/package.json index f80d30061aa60c..4a5d9c89786733 100644 --- a/packages/zone.js/test/typings/package.json +++ b/packages/zone.js/test/typings/package.json @@ -14,6 +14,6 @@ "zone.js": "file:../../../../dist/bin/packages/zone.js/npm_package" }, "devDependencies": { - "typescript": "~4.2.4" + "typescript": "~4.3.0-dev.20210510" } } diff --git a/packages/zone.js/yarn.lock b/packages/zone.js/yarn.lock index 9cdf16e8a05ee7..e029c3fa2ea38e 100644 --- a/packages/zone.js/yarn.lock +++ b/packages/zone.js/yarn.lock @@ -4094,7 +4094,7 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -tslib@^2.1.0: +tslib@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== @@ -4145,10 +4145,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +typescript@4.3.0-dev.20210510: + version "4.3.0-dev.20210510" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.0-dev.20210510.tgz#a50dd4f9a6e616f82cb33148c7f5ee80cc07857b" + integrity sha512-HR21ZkELulLWOHfHIA57/6rD1rkadgjyMp1TVeXQ5v82/rn0V3ROkAnd1elt+Mrjc2pTXcIwom7E/N5RCUUxMg== unbox-primitive@^1.0.0: version "1.0.1" diff --git a/tools/ts-api-guardian/package.json b/tools/ts-api-guardian/package.json index b26ed5bce7a28b..b093a4868a3684 100644 --- a/tools/ts-api-guardian/package.json +++ b/tools/ts-api-guardian/package.json @@ -25,7 +25,7 @@ "@types/node": "^10.9.4", "jasmine": "^3.1.0", "source-map-support": "^0.5.9", - "typescript": "4.2.4" + "typescript": "4.3.0-dev.20210510" }, "keywords": [ "typescript" diff --git a/yarn.lock b/yarn.lock index dffc956a2f3a52..38b70bdf189e4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13207,7 +13207,7 @@ tslib@1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== -tslib@2.2.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.2.0: +tslib@2.2.0, tslib@^2.0.1, tslib@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== @@ -13368,7 +13368,7 @@ typescript@3.2.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== -typescript@4.2.4, typescript@~4.2.4: +typescript@4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== @@ -13383,6 +13383,11 @@ typescript@~3.7.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.7.tgz#c931733e2ec10dda56b855b379cc488a72a81199" integrity sha512-MmQdgo/XenfZPvVLtKZOq9jQQvzaUAUpcKW8Z43x9B2fOm4S5g//tPtMweZUIP+SoBqrVPEIm+dJeQ9dfO0QdA== +typescript@~4.3.0-dev.20210510: + version "4.3.0-dev.20210510" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.0-dev.20210510.tgz#a50dd4f9a6e616f82cb33148c7f5ee80cc07857b" + integrity sha512-HR21ZkELulLWOHfHIA57/6rD1rkadgjyMp1TVeXQ5v82/rn0V3ROkAnd1elt+Mrjc2pTXcIwom7E/N5RCUUxMg== + uglify-js@^3.1.4: version "3.13.7" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.7.tgz#25468a3b39b1c875df03f0937b2b7036a93f3fee"