mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(core): support TypeScript 4.5 (#44164)
Adds support for TypeScript 4.5. Includes the following changes: * Bumping the package versions. * Fixing a few calls to `createExportSpecifier` and `createImportSpecifier` that require an extra parameter. * Adding some missing methods to the TS compiler hosts. * Fixing an issue in the TS mocks for the ngcc tests where a regex was too agressive and was trying to match a path like `/node_modules/@typescript/lib-es5`. * Accounting for type-only import specifiers when reporting DI errors (see #43620). Fixes #43620. PR Close #44164
This commit is contained in:
committed by
Dylan Hunn
parent
0fcf18d5f4
commit
d56e3f43a1
@@ -49,6 +49,6 @@
|
||||
"supertest": "^4.0.2",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||
"typescript": "~4.4.2"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2563,10 +2563,10 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typescript@~4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.2.tgz#6d618640d430e3569a1dfb44f7d7e600ced3ee86"
|
||||
integrity sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==
|
||||
typescript@~4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998"
|
||||
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
|
||||
|
||||
undefsafe@^2.0.2:
|
||||
version "2.0.2"
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@
|
||||
"ts-node": "^10.0.0",
|
||||
"tsec": "^0.1.5",
|
||||
"tslint": "~6.1.3",
|
||||
"typescript": "~4.4.3",
|
||||
"typescript": "~4.5.2",
|
||||
"uglify-js": "^3.13.3",
|
||||
"unist-util-filter": "^2.0.3",
|
||||
"unist-util-source": "^3.0.0",
|
||||
|
||||
@@ -46,6 +46,6 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,6 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,6 @@
|
||||
"rollup-plugin-commonjs": "^9.2.1",
|
||||
"rollup-plugin-node-resolve": "^4.0.0",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,6 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,6 @@
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"source-map-explorer": "^1.3.2",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.4.3"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11066,10 +11066,10 @@ typed-assert@^1.0.8:
|
||||
resolved "https://registry.yarnpkg.com/typed-assert/-/typed-assert-1.0.8.tgz#4bf9f1ce7f3f974d09c3afd7c68d12e1391a233c"
|
||||
integrity sha512-5NkbXZUlmCE73Fs7gvkp1XXJWHYetPkg60QnQ2NXQmBYNFxbBr2zA8GCtaH4K2s2WhOmSlgiSTmrjrcm5tnM5g==
|
||||
|
||||
typescript@~4.4.3:
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
|
||||
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
|
||||
typescript@~4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998"
|
||||
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
|
||||
|
||||
ua-parser-js@0.7.17:
|
||||
version "0.7.17"
|
||||
|
||||
+4
-4
@@ -11776,10 +11776,10 @@ typescript@~3.2.2:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d"
|
||||
integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==
|
||||
|
||||
typescript@~4.4.3:
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
|
||||
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
|
||||
typescript@~4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998"
|
||||
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
|
||||
|
||||
ua-parser-js@^0.7.30:
|
||||
version "0.7.31"
|
||||
|
||||
@@ -100,6 +100,12 @@ INTEGRATION_TESTS = {
|
||||
# root @npm//typescript package.
|
||||
"pinned_npm_packages": ["typescript"],
|
||||
},
|
||||
"typings_test_ts45": {
|
||||
# Special case for `typings_test_ts45` test as we want to pin
|
||||
# `typescript` at version 4.5.x for that test and not link to the
|
||||
# root @npm//typescript package.
|
||||
"pinned_npm_packages": ["typescript"],
|
||||
},
|
||||
}
|
||||
|
||||
[
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "angular-integration",
|
||||
"description": "Assert that users with TypeScript 4.5 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.5.2",
|
||||
"zone.js": "file:../../dist/zone.js-dist/archive/zone.js.tgz"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tsc"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -152,7 +152,7 @@
|
||||
"tsickle": "0.38.1",
|
||||
"tslib": "^2.3.0",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "~4.4.2",
|
||||
"typescript": "~4.5.2",
|
||||
"xhr2": "0.2.1",
|
||||
"yargs": "^17.2.1"
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"rollup": "^2.56.3",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"terser": "^5.9.0",
|
||||
"typescript": ">=4.4.2 <4.5"
|
||||
"typescript": ">=4.4.2 <4.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"terser": {
|
||||
|
||||
@@ -105,6 +105,7 @@ ts_library(
|
||||
"//packages/compiler-cli/src/ngtsc/translator",
|
||||
"//packages/compiler-cli/src/ngtsc/typecheck",
|
||||
"//packages/compiler-cli/src/ngtsc/typecheck/api",
|
||||
"//packages/compiler-cli/src/ngtsc/util",
|
||||
"//packages/compiler-cli/src/transformers/downlevel_decorators_transform",
|
||||
"@npm//@bazel/typescript",
|
||||
"@npm//@types/node",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {DepGraph} from 'dependency-graph';
|
||||
|
||||
import {DtsProcessing, PartiallyOrderedTasks} from '../../src/execution/tasks/api';
|
||||
import {EntryPoint, EntryPointJsonProperty} from '../../src/packages/entry_point';
|
||||
|
||||
@@ -53,7 +54,7 @@ export function createTasksAndGraph(
|
||||
|
||||
for (let tIdx = 0; tIdx < tasksPerEntryPointCount; tIdx++) {
|
||||
const processDts = tIdx === 0 ? DtsProcessing.Yes : DtsProcessing.No;
|
||||
const formatProperty = `prop-${tIdx}` as EntryPointJsonProperty;
|
||||
const formatProperty = `prop-${tIdx}` as unknown as EntryPointJsonProperty;
|
||||
tasks.push({
|
||||
entryPoint,
|
||||
formatProperty: formatProperty,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {MockLogger} from '../../../../../src/ngtsc/logging/testing';
|
||||
import {DtsProcessing, PartiallyOrderedTasks, Task, TaskQueue} from '../../../../src/execution/tasks/api';
|
||||
import {SerialTaskQueue} from '../../../../src/execution/tasks/queues/serial_task_queue';
|
||||
import {computeTaskDependencies} from '../../../../src/execution/tasks/utils';
|
||||
import {EntryPoint} from '../../../../src/packages/entry_point';
|
||||
import {EntryPoint, EntryPointJsonProperty} from '../../../../src/packages/entry_point';
|
||||
|
||||
|
||||
describe('SerialTaskQueue', () => {
|
||||
@@ -35,7 +35,7 @@ describe('SerialTaskQueue', () => {
|
||||
const processDts = i % 2 === 0 ? DtsProcessing.Yes : DtsProcessing.No;
|
||||
tasks.push({
|
||||
entryPoint: entryPoint,
|
||||
formatProperty: `prop-${i}`,
|
||||
formatProperty: `prop-${i}` as unknown as EntryPointJsonProperty,
|
||||
formatPropertiesToMarkAsProcessed: [],
|
||||
processDts
|
||||
} as Task);
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler": "0.0.0-PLACEHOLDER",
|
||||
"typescript": ">=4.4.2 <4.5"
|
||||
"typescript": ">=4.4.2 <4.6"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -219,7 +219,7 @@ function createUnsuitableInjectionTokenError(
|
||||
makeRelatedInformation(
|
||||
reason.typeNode,
|
||||
'This type is imported using a type-only import, which prevents it from being usable as an injection token.'),
|
||||
makeRelatedInformation(reason.importClause, 'The type-only import occurs here.'),
|
||||
makeRelatedInformation(reason.node, 'The type-only import occurs here.'),
|
||||
];
|
||||
break;
|
||||
case ValueUnavailableKind.NAMESPACE:
|
||||
|
||||
@@ -67,6 +67,10 @@ export class DelegatingCompilerHost implements
|
||||
trace = this.delegateMethod('trace');
|
||||
useCaseSensitiveFileNames = this.delegateMethod('useCaseSensitiveFileNames');
|
||||
writeFile = this.delegateMethod('writeFile');
|
||||
|
||||
// TODO(crisbeto): the cast to `any` is here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
getModuleResolutionCache = this.delegateMethod('getModuleResolutionCache' as any);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -92,7 +92,7 @@ export class ImportGraph {
|
||||
}
|
||||
|
||||
if (ts.isImportDeclaration(stmt) && stmt.importClause !== undefined &&
|
||||
stmt.importClause.isTypeOnly) {
|
||||
isTypeOnlyImportClause(stmt.importClause)) {
|
||||
// Exclude type-only imports as they are always elided, so they don't contribute to
|
||||
// cycles.
|
||||
continue;
|
||||
@@ -118,6 +118,23 @@ function isLocalFile(sf: ts.SourceFile): boolean {
|
||||
return !sf.isDeclarationFile;
|
||||
}
|
||||
|
||||
function isTypeOnlyImportClause(node: ts.ImportClause): boolean {
|
||||
// The clause itself is type-only (e.g. `import type {foo} from '...'`).
|
||||
if (node.isTypeOnly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// All the specifiers in the cause are type-only (e.g. `import {type a, type b} from '...'`).
|
||||
if (node.namedBindings !== undefined && ts.isNamedImports(node.namedBindings) &&
|
||||
// TODO(crisbeto): the cast to `any` is here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
node.namedBindings.elements.every(specifier => (specifier as any).isTypeOnly)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class to track which SourceFiles are being processed when searching for a path in
|
||||
* `getPath()` above.
|
||||
|
||||
@@ -51,6 +51,10 @@ export class DelegatingCompilerHost implements
|
||||
resolveTypeReferenceDirectives = this.delegateMethod('resolveTypeReferenceDirectives');
|
||||
trace = this.delegateMethod('trace');
|
||||
useCaseSensitiveFileNames = this.delegateMethod('useCaseSensitiveFileNames');
|
||||
|
||||
// TODO(crisbeto): the cast to `any` is here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
getModuleResolutionCache = this.delegateMethod('getModuleResolutionCache' as any);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -342,7 +342,7 @@ export interface NoValueDeclaration {
|
||||
export interface TypeOnlyImport {
|
||||
kind: ValueUnavailableKind.TYPE_ONLY_IMPORT;
|
||||
typeNode: ts.TypeNode;
|
||||
importClause: ts.ImportClause;
|
||||
node: ts.ImportClause|ts.ImportSpecifier;
|
||||
}
|
||||
|
||||
export interface NamespaceImport {
|
||||
|
||||
@@ -72,8 +72,16 @@ export function typeToValue(
|
||||
// or
|
||||
// import {Foo as Bar} from 'foo';
|
||||
|
||||
// TODO(crisbeto): the cast to `any` is here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
if ((firstDecl as any).isTypeOnly) {
|
||||
// The import specifier can't be type-only (e.g. `import {type Foo} from '...')`.
|
||||
return typeOnlyImport(typeNode, firstDecl);
|
||||
}
|
||||
|
||||
if (firstDecl.parent.parent.isTypeOnly) {
|
||||
// Type-only imports cannot be represented as value.
|
||||
// The import specifier can't be inside a type-only import clause
|
||||
// (e.g. `import type {Foo} from '...')`.
|
||||
return typeOnlyImport(typeNode, firstDecl.parent.parent);
|
||||
}
|
||||
|
||||
@@ -151,11 +159,11 @@ function noValueDeclaration(
|
||||
};
|
||||
}
|
||||
|
||||
function typeOnlyImport(
|
||||
typeNode: ts.TypeNode, importClause: ts.ImportClause): UnavailableTypeValueReference {
|
||||
function typeOnlyImport(typeNode: ts.TypeNode, node: ts.ImportClause|ts.ImportSpecifier):
|
||||
UnavailableTypeValueReference {
|
||||
return {
|
||||
kind: TypeValueReferenceKind.UNAVAILABLE,
|
||||
reason: {kind: ValueUnavailableKind.TYPE_ONLY_IMPORT, typeNode, importClause},
|
||||
reason: {kind: ValueUnavailableKind.TYPE_ONLY_IMPORT, typeNode, node},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,8 @@ export class AdapterResourceLoader implements ResourceLoader {
|
||||
*/
|
||||
function createLookupResolutionHost(adapter: NgCompilerAdapter):
|
||||
RequiredDelegations<ts.ModuleResolutionHost> {
|
||||
// TODO(crisbeto): the cast to `any` is here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
return {
|
||||
directoryExists(directoryName: string): boolean {
|
||||
if (directoryName.includes(RESOURCE_MARKER)) {
|
||||
@@ -261,5 +263,8 @@ function createLookupResolutionHost(adapter: NgCompilerAdapter):
|
||||
getDirectories: adapter.getDirectories?.bind(adapter),
|
||||
realpath: adapter.realpath?.bind(adapter),
|
||||
trace: adapter.trace?.bind(adapter),
|
||||
};
|
||||
useCaseSensitiveFileNames: typeof (adapter as any).useCaseSensitiveFileNames === 'function' ?
|
||||
(adapter as any).useCaseSensitiveFileNames.bind(adapter) :
|
||||
(adapter as any).useCaseSensitiveFileNames
|
||||
} as any;
|
||||
}
|
||||
|
||||
@@ -159,9 +159,11 @@ function transformFactorySourceFile(
|
||||
const rewrittenModuleSpecifier =
|
||||
importRewriter.rewriteSpecifier('@angular/core', sourceFilePath);
|
||||
if (rewrittenModuleSpecifier !== stmt.moduleSpecifier.text) {
|
||||
transformedStatements.push(ts.updateImportDeclaration(
|
||||
// TODO(crisbeto): the cast to `any` is here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
transformedStatements.push((ts.updateImportDeclaration as any)(
|
||||
stmt, stmt.decorators, stmt.modifiers, stmt.importClause,
|
||||
ts.createStringLiteral(rewrittenModuleSpecifier)));
|
||||
ts.createStringLiteral(rewrittenModuleSpecifier), undefined));
|
||||
|
||||
// Record the identifier by which this imported module goes, so references to its symbols
|
||||
// can be discovered later.
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
import ts from 'typescript';
|
||||
|
||||
import {createExportSpecifier} from '../../util/src/typescript';
|
||||
|
||||
export function aliasTransformFactory(exportStatements: Map<string, Map<string, [string, string]>>):
|
||||
ts.TransformerFactory<ts.SourceFile> {
|
||||
return (context: ts.TransformationContext) => {
|
||||
@@ -21,9 +23,8 @@ export function aliasTransformFactory(exportStatements: Map<string, Map<string,
|
||||
const stmt = ts.createExportDeclaration(
|
||||
/* decorators */ undefined,
|
||||
/* modifiers */ undefined,
|
||||
/* exportClause */ ts.createNamedExports([ts.createExportSpecifier(
|
||||
/* propertyName */ symbolName,
|
||||
/* name */ aliasName)]),
|
||||
/* exportClause */ ts.createNamedExports([createExportSpecifier(
|
||||
symbolName, aliasName)]),
|
||||
/* moduleSpecifier */ ts.createStringLiteral(moduleName));
|
||||
statements.push(stmt);
|
||||
});
|
||||
|
||||
@@ -13,6 +13,8 @@ import ts from 'typescript';
|
||||
import {AbsoluteFsPath, getFileSystem} from '../../file_system';
|
||||
import {DeclarationNode} from '../../reflection';
|
||||
|
||||
const PARSED_TS_VERSION = parseFloat(ts.versionMajorMinor);
|
||||
|
||||
/**
|
||||
* Type describing a symbol that is guaranteed to have a value declaration.
|
||||
*/
|
||||
@@ -203,3 +205,36 @@ export function toUnredirectedSourceFile(sf: ts.SourceFile): ts.SourceFile {
|
||||
}
|
||||
return redirectInfo.unredirected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards-compatible version of `ts.createExportSpecifier`
|
||||
* to handle a breaking change between 4.4 and 4.5.
|
||||
*/
|
||||
export function createExportSpecifier(
|
||||
propertyName: string|ts.Identifier|undefined, name: string|ts.Identifier,
|
||||
isTypeOnly = false): ts.ExportSpecifier {
|
||||
return PARSED_TS_VERSION > 4.4 ?
|
||||
// TODO(crisbeto): the function is cast to `any` here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
(ts.createExportSpecifier as any)(isTypeOnly, propertyName, name) :
|
||||
// TODO(crisbeto): backwards-compatibility layer for TS 4.4.
|
||||
// Should be cleaned up when we drop support for it.
|
||||
(ts.createExportSpecifier as any)(propertyName, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backwards-compatible version of `ts.createImportSpecifier`
|
||||
* to handle a breaking change between 4.4 and 4.5.
|
||||
*/
|
||||
export function createImportSpecifier(
|
||||
propertyName: string|ts.Identifier|undefined, name: string|ts.Identifier,
|
||||
isTypeOnly = false): ts.ImportSpecifier {
|
||||
return PARSED_TS_VERSION > 4.4 ?
|
||||
// TODO(crisbeto): the function is cast to `any` here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
(ts.createImportSpecifier as any)(isTypeOnly, propertyName, name) :
|
||||
// TODO(crisbeto): backwards-compatibility layer for TS 4.4.
|
||||
// Should be cleaned up when we drop support for it.
|
||||
(ts.createImportSpecifier as any)(propertyName, name);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {createLoweredSymbol, isLoweredSymbol} from '@angular/compiler';
|
||||
import ts from 'typescript';
|
||||
|
||||
import {CollectorOptions, isMetadataGlobalReferenceExpression, MetadataCollector, MetadataValue, ModuleMetadata} from '../metadata/index';
|
||||
import {createExportSpecifier} from '../ngtsc/util/src/typescript';
|
||||
|
||||
import {MetadataCache, MetadataTransformer, ValueTransform} from './metadata_cache';
|
||||
|
||||
@@ -162,7 +163,7 @@ function transformSourceFile(
|
||||
(accumulator, insert) => [...accumulator, ...insert.declarations],
|
||||
[] as Declaration[])
|
||||
.map(
|
||||
declaration => ts.createExportSpecifier(
|
||||
declaration => createExportSpecifier(
|
||||
/* propertyName */ undefined, declaration.name)))));
|
||||
|
||||
newStatements = tmpStatements;
|
||||
|
||||
@@ -10,6 +10,8 @@ import {AssertNotNull, BinaryOperator, BinaryOperatorExpr, BuiltinMethod, Builti
|
||||
import ts from 'typescript';
|
||||
|
||||
import {attachComments} from '../ngtsc/translator';
|
||||
import {createExportSpecifier} from '../ngtsc/util/src/typescript';
|
||||
|
||||
import {error} from './util';
|
||||
|
||||
export interface Node {
|
||||
@@ -222,7 +224,7 @@ export class NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
||||
/* decorators */ undefined,
|
||||
/* modifiers */ undefined,
|
||||
ts.createNamedExports(
|
||||
reexports.map(({name, as}) => ts.createExportSpecifier(name, as))),
|
||||
reexports.map(({name, as}) => createExportSpecifier(name, as))),
|
||||
/* moduleSpecifier */ createLiteral(exportedFilePath)));
|
||||
}
|
||||
|
||||
@@ -350,7 +352,7 @@ export class NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
||||
stmt,
|
||||
ts.createExportDeclaration(
|
||||
/*decorators*/ undefined, /*modifiers*/ undefined,
|
||||
ts.createNamedExports([ts.createExportSpecifier(stmt.name, stmt.name)])));
|
||||
ts.createNamedExports([createExportSpecifier(stmt.name, stmt.name)])));
|
||||
return [tsVarStmt, exportStmt];
|
||||
}
|
||||
return this.postProcess(stmt, ts.createVariableStatement(this.getModifiers(stmt), varDeclList));
|
||||
@@ -751,22 +753,6 @@ export class NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
function getMethodName(methodRef: {name: string|null; builtin: BuiltinMethod | null}): string {
|
||||
if (methodRef.name) {
|
||||
return methodRef.name;
|
||||
} else {
|
||||
switch (methodRef.builtin) {
|
||||
case BuiltinMethod.Bind:
|
||||
return 'bind';
|
||||
case BuiltinMethod.ConcatArray:
|
||||
return 'concat';
|
||||
case BuiltinMethod.SubscribeObservable:
|
||||
return 'subscribe';
|
||||
}
|
||||
}
|
||||
throw new Error('Unexpected method reference form');
|
||||
}
|
||||
|
||||
function modifierFromModifier(modifier: StmtModifier): ts.Modifier {
|
||||
switch (modifier) {
|
||||
case StmtModifier.Exported:
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import ts from 'typescript';
|
||||
|
||||
import {compareVersions} from './diagnostics/typescript_version';
|
||||
|
||||
/**
|
||||
@@ -25,7 +26,7 @@ const MIN_TS_VERSION = '4.4.2';
|
||||
* Note: this check is disabled in g3, search for
|
||||
* `angularCompilerOptions.disableTypeScriptVersionCheck` config param value in g3.
|
||||
*/
|
||||
const MAX_TS_VERSION = '4.5.0';
|
||||
const MAX_TS_VERSION = '4.6.0';
|
||||
|
||||
/**
|
||||
* The currently used version of TypeScript, which can be adjusted for testing purposes using
|
||||
|
||||
@@ -67,7 +67,7 @@ export class Host implements ts.LanguageServiceHost {
|
||||
if (this.overrides.has(fileName)) {
|
||||
return this.overrides.get(fileName);
|
||||
}
|
||||
if (/lib(.*)\.d\.ts/.test(fileName)) {
|
||||
if (/^lib(.*)\.d\.ts/.test(fileName)) {
|
||||
const libDirPath = path.dirname(ts.getDefaultLibFilePath(this.getCompilationSettings()));
|
||||
const libPath = path.join(libDirPath, fileName);
|
||||
return fs.readFileSync(libPath, 'utf8');
|
||||
|
||||
@@ -2380,36 +2380,69 @@ function allTests(os: string) {
|
||||
.toBe('This type is not supported as injection token.');
|
||||
});
|
||||
|
||||
it('should report an error when using a type-only import as injection token', () => {
|
||||
env.tsconfig({strictInjectionParameters: true});
|
||||
env.write(`types.ts`, `
|
||||
export class TypeOnly {}
|
||||
`);
|
||||
env.write(`test.ts`, `
|
||||
import {Injectable} from '@angular/core';
|
||||
import type {TypeOnly} from './types';
|
||||
it('should report an error when using a symbol from a type-only import clause as injection token',
|
||||
() => {
|
||||
env.tsconfig({strictInjectionParameters: true});
|
||||
env.write(`types.ts`, `
|
||||
export class TypeOnly {}
|
||||
`);
|
||||
env.write(`test.ts`, `
|
||||
import {Injectable} from '@angular/core';
|
||||
import type {TypeOnly} from './types';
|
||||
|
||||
@Injectable()
|
||||
export class MyService {
|
||||
constructor(param: TypeOnly) {}
|
||||
}
|
||||
`);
|
||||
@Injectable()
|
||||
export class MyService {
|
||||
constructor(param: TypeOnly) {}
|
||||
}
|
||||
`);
|
||||
|
||||
const diags = env.driveDiagnostics();
|
||||
expect(diags.length).toBe(1);
|
||||
expect(ts.flattenDiagnosticMessageText(diags[0].messageText, '\n'))
|
||||
.toBe(
|
||||
`No suitable injection token for parameter 'param' of class 'MyService'.\n` +
|
||||
` Consider changing the type-only import to a regular import, ` +
|
||||
`or use the @Inject decorator to specify an injection token.`);
|
||||
expect(diags[0].relatedInformation!.length).toBe(2);
|
||||
expect(diags[0].relatedInformation![0].messageText)
|
||||
.toBe(
|
||||
'This type is imported using a type-only import, ' +
|
||||
'which prevents it from being usable as an injection token.');
|
||||
expect(diags[0].relatedInformation![1].messageText)
|
||||
.toBe('The type-only import occurs here.');
|
||||
});
|
||||
const diags = env.driveDiagnostics();
|
||||
expect(diags.length).toBe(1);
|
||||
expect(ts.flattenDiagnosticMessageText(diags[0].messageText, '\n'))
|
||||
.toBe(
|
||||
`No suitable injection token for parameter 'param' of class 'MyService'.\n` +
|
||||
` Consider changing the type-only import to a regular import, ` +
|
||||
`or use the @Inject decorator to specify an injection token.`);
|
||||
expect(diags[0].relatedInformation!.length).toBe(2);
|
||||
expect(diags[0].relatedInformation![0].messageText)
|
||||
.toBe(
|
||||
'This type is imported using a type-only import, ' +
|
||||
'which prevents it from being usable as an injection token.');
|
||||
expect(diags[0].relatedInformation![1].messageText)
|
||||
.toBe('The type-only import occurs here.');
|
||||
});
|
||||
|
||||
it('should report an error when using a symbol from a type-only import specifier as injection token',
|
||||
() => {
|
||||
env.tsconfig({strictInjectionParameters: true});
|
||||
env.write(`types.ts`, `
|
||||
export class TypeOnly {}
|
||||
`);
|
||||
env.write(`test.ts`, `
|
||||
import {Injectable} from '@angular/core';
|
||||
import {type TypeOnly} from './types';
|
||||
|
||||
@Injectable()
|
||||
export class MyService {
|
||||
constructor(param: TypeOnly) {}
|
||||
}
|
||||
`);
|
||||
|
||||
const diags = env.driveDiagnostics();
|
||||
expect(diags.length).toBe(1);
|
||||
expect(ts.flattenDiagnosticMessageText(diags[0].messageText, '\n'))
|
||||
.toBe(
|
||||
`No suitable injection token for parameter 'param' of class 'MyService'.\n` +
|
||||
` Consider changing the type-only import to a regular import, ` +
|
||||
`or use the @Inject decorator to specify an injection token.`);
|
||||
expect(diags[0].relatedInformation!.length).toBe(2);
|
||||
expect(diags[0].relatedInformation![0].messageText)
|
||||
.toBe(
|
||||
'This type is imported using a type-only import, ' +
|
||||
'which prevents it from being usable as an injection token.');
|
||||
expect(diags[0].relatedInformation![1].messageText)
|
||||
.toBe('The type-only import occurs here.');
|
||||
});
|
||||
|
||||
it('should report an error when using a primitive type as injection token', () => {
|
||||
env.tsconfig({strictInjectionParameters: true});
|
||||
@@ -4770,12 +4803,14 @@ function allTests(os: string) {
|
||||
() => {
|
||||
env.write(`types.ts`, `
|
||||
export default class {}
|
||||
export class TypeOnly {}
|
||||
export class TypeOnlyOne {}
|
||||
export class TypeOnlyTwo {}
|
||||
`);
|
||||
env.write(`test.ts`, `
|
||||
import {Component, Inject, Injectable} from '@angular/core';
|
||||
import type DefaultImport from './types';
|
||||
import type {TypeOnly} from './types';
|
||||
import type {TypeOnlyOne} from './types';
|
||||
import {type TypeOnlyTwo} from './types';
|
||||
import type * as types from './types';
|
||||
|
||||
@Component({
|
||||
@@ -4784,9 +4819,10 @@ function allTests(os: string) {
|
||||
})
|
||||
export class SomeComp {
|
||||
constructor(
|
||||
@Inject('token') namedImport: TypeOnly,
|
||||
@Inject('token') namedImport: TypeOnlyOne,
|
||||
@Inject('token') defaultImport: DefaultImport,
|
||||
@Inject('token') namespacedImport: types.TypeOnly,
|
||||
@Inject('token') namespacedImport: types.TypeOnlyOne,
|
||||
@Inject('token') typeOnlySpecifier: TypeOnlyTwo,
|
||||
) {}
|
||||
}
|
||||
`);
|
||||
@@ -4798,7 +4834,9 @@ function allTests(os: string) {
|
||||
// Default type-only import should not be emitted
|
||||
expect(jsContents).not.toContain('DefaultImport');
|
||||
// Named type-only import should not be emitted
|
||||
expect(jsContents).not.toContain('TypeOnly');
|
||||
expect(jsContents).not.toContain('TypeOnlyOne');
|
||||
// Symbols from type-only specifiers should not be emitted
|
||||
expect(jsContents).not.toContain('TypeOnlyTwo');
|
||||
// The parameter type in class metadata should be undefined
|
||||
expect(jsContents).toMatch(setClassMetadataRegExp('type: undefined'));
|
||||
});
|
||||
@@ -4950,7 +4988,7 @@ function allTests(os: string) {
|
||||
expect(jsContents).not.toContain('setComponentScope');
|
||||
});
|
||||
|
||||
it('should not consider type-only imports during cycle detection', () => {
|
||||
it('should not consider type-only import clauses during cycle detection', () => {
|
||||
env.write('test.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {ACmp} from './a';
|
||||
@@ -4985,6 +5023,50 @@ function allTests(os: string) {
|
||||
expect(jsContents).not.toContain('setComponentScope');
|
||||
});
|
||||
|
||||
it('should not consider import clauses where all the specifiers are type-only during cycle detection',
|
||||
() => {
|
||||
env.write('test.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {SharedOne, SharedTwo} from './shared';
|
||||
import {CyclicCmp} from './cyclic';
|
||||
|
||||
@NgModule({declarations: [SharedOne, SharedTwo, CyclicCmp]})
|
||||
export class Module {}
|
||||
`);
|
||||
env.write('shared.ts', `
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-one-cmp',
|
||||
template: '<cyclic-cmp></cyclic-cmp>',
|
||||
})
|
||||
export class SharedOne {}
|
||||
|
||||
@Component({
|
||||
selector: 'shared-two-cmp',
|
||||
template: '<cyclic-cmp></cyclic-cmp>',
|
||||
})
|
||||
export class SharedTwo {}
|
||||
`);
|
||||
env.write('cyclic.ts', `
|
||||
import {Component} from '@angular/core';
|
||||
import {type SharedOne, type SharedTwo} from './shared';
|
||||
|
||||
@Component({
|
||||
selector: 'cyclic-cmp',
|
||||
template: 'does not use shared components',
|
||||
})
|
||||
export class CyclicCmp {
|
||||
one: SharedOne;
|
||||
two: SharedTwo;
|
||||
}
|
||||
`);
|
||||
|
||||
env.driveMain();
|
||||
const jsContents = env.getContents('test.js');
|
||||
expect(jsContents).not.toContain('setComponentScope');
|
||||
});
|
||||
|
||||
it('should only pass components actually used to setComponentScope', () => {
|
||||
env.write('test.ts', `
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
import {dirname, resolve} from 'path';
|
||||
import ts from 'typescript';
|
||||
|
||||
const PARSED_TS_VERSION = parseFloat(ts.versionMajorMinor);
|
||||
|
||||
/** Update recorder for managing imports. */
|
||||
export interface ImportManagerUpdateRecorder {
|
||||
addNewImport(start: number, importText: string): void;
|
||||
@@ -151,7 +153,7 @@ export class ImportManager {
|
||||
undefined, undefined,
|
||||
ts.createImportClause(
|
||||
undefined,
|
||||
ts.createNamedImports([ts.createImportSpecifier(
|
||||
ts.createNamedImports([createImportSpecifier(
|
||||
needsGeneratedUniqueName ? propertyIdentifier : undefined, identifier)])),
|
||||
ts.createStringLiteral(moduleName));
|
||||
} else {
|
||||
@@ -190,7 +192,7 @@ export class ImportManager {
|
||||
const newNamedBindings = ts.updateNamedImports(
|
||||
namedBindings,
|
||||
namedBindings.elements.concat(expressions.map(
|
||||
({propertyName, importName}) => ts.createImportSpecifier(propertyName, importName))));
|
||||
({propertyName, importName}) => createImportSpecifier(propertyName, importName))));
|
||||
|
||||
const newNamedBindingsText =
|
||||
this.printer.printNode(ts.EmitHint.Unspecified, newNamedBindings, sourceFile);
|
||||
@@ -257,3 +259,20 @@ export class ImportManager {
|
||||
return commentRanges[commentRanges.length - 1]!.end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backwards-compatible version of `ts.createImportSpecifier`
|
||||
* to handle a breaking change between 4.4 and 4.5.
|
||||
*/
|
||||
export function createImportSpecifier(
|
||||
propertyName: string|ts.Identifier|undefined, name: string|ts.Identifier,
|
||||
isTypeOnly = false): ts.ImportSpecifier {
|
||||
return PARSED_TS_VERSION > 4.4 ?
|
||||
// TODO(crisbeto): the function is cast to `any` here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
(ts.createImportSpecifier as any)(isTypeOnly, propertyName, name) :
|
||||
// TODO(crisbeto): backwards-compatibility layer for TS 4.4.
|
||||
// Should be cleaned up when we drop support for it.
|
||||
(ts.createImportSpecifier as any)(propertyName, name);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ export type Import = {
|
||||
node: ts.ImportDeclaration
|
||||
};
|
||||
|
||||
const PARSED_TS_VERSION = parseFloat(ts.versionMajorMinor);
|
||||
|
||||
/** Gets import information about the specified identifier by using the Type checker. */
|
||||
export function getImportOfIdentifier(typeChecker: ts.TypeChecker, node: ts.Identifier): Import|
|
||||
null {
|
||||
@@ -98,13 +100,21 @@ export function replaceImport(
|
||||
return node;
|
||||
}
|
||||
|
||||
const importPropertyName =
|
||||
existingImportNode.propertyName ? ts.createIdentifier(newImportName) : undefined;
|
||||
const importName = existingImportNode.propertyName ? existingImportNode.name :
|
||||
ts.createIdentifier(newImportName);
|
||||
|
||||
return ts.updateNamedImports(node, [
|
||||
...node.elements.filter(current => current !== existingImportNode),
|
||||
// Create a new import while trying to preserve the alias of the old one.
|
||||
ts.createImportSpecifier(
|
||||
existingImportNode.propertyName ? ts.createIdentifier(newImportName) : undefined,
|
||||
existingImportNode.propertyName ? existingImportNode.name :
|
||||
ts.createIdentifier(newImportName))
|
||||
PARSED_TS_VERSION > 4.4 ?
|
||||
// TODO(crisbeto): the function is cast to `any` here since g3 is still on TS 4.4.
|
||||
// Should be cleaned up when g3 has been updated.
|
||||
(ts.createImportSpecifier as any)(false, importPropertyName, importName) :
|
||||
// TODO(crisbeto): backwards-compatibility layer for TS 4.4.
|
||||
// Should be cleaned up when we drop support for it.
|
||||
(ts.createImportSpecifier as any)(importPropertyName, importName)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"mocha": "^9.0.0",
|
||||
"mock-require": "3.0.3",
|
||||
"promises-aplus-tests": "^2.1.2",
|
||||
"typescript": "~4.4.2"
|
||||
"typescript": "~4.5.2"
|
||||
},
|
||||
"scripts": {
|
||||
"closuretest": "./scripts/closure/closure_compiler.sh",
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
"zone.js": "file:../../../../dist/bin/packages/zone.js/npm_package"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "~4.4.2"
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3983,10 +3983,10 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typescript@~4.4.2:
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
|
||||
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
|
||||
typescript@~4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998"
|
||||
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
|
||||
|
||||
unbox-primitive@^1.0.1:
|
||||
version "1.0.1"
|
||||
|
||||
@@ -14104,6 +14104,11 @@ typescript@^3.9.5, typescript@^3.9.7:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
|
||||
integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
|
||||
|
||||
typescript@~4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998"
|
||||
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
|
||||
|
||||
ua-parser-js@^0.7.21, ua-parser-js@^0.7.30:
|
||||
version "0.7.31"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"
|
||||
|
||||
Reference in New Issue
Block a user