build: prepare for TypeScript 3.9 (#36989)

- Fix several compilation errors
- Update @microsoft/api-extractor to be compatible with TypeScript 3.9

PR Close #36989
This commit is contained in:
Alan Agius
2020-05-12 08:19:59 +01:00
committed by Kara Erickson
parent b58bd2bb91
commit 13ba84731f
28 changed files with 384 additions and 855 deletions

View File

@ -8,16 +8,16 @@
import {NodeJSFileSystem, setFileSystem} from '../src/ngtsc/file_system';
import {mainNgcc} from './src/main';
import {AsyncNgccOptions, NgccOptions, SyncNgccOptions} from './src/ngcc_options';
import {AsyncNgccOptions, SyncNgccOptions} from './src/ngcc_options';
export {ConsoleLogger} from './src/logging/console_logger';
export {Logger, LogLevel} from './src/logging/logger';
export {AsyncNgccOptions, NgccOptions, SyncNgccOptions} from './src/ngcc_options';
export {PathMappings} from './src/path_mappings';
export function process(options: AsyncNgccOptions): Promise<void>;
export function process(options: SyncNgccOptions): void;
export function process(options: NgccOptions): void|Promise<void> {
export function process<T extends AsyncNgccOptions|SyncNgccOptions>(options: T):
T extends AsyncNgccOptions ? Promise<void>: void;
export function process(options: AsyncNgccOptions|SyncNgccOptions): void|Promise<void> {
setFileSystem(new NodeJSFileSystem());
return mainNgcc(options);
}

View File

@ -32,7 +32,7 @@ import {AsyncLocker} from './locking/async_locker';
import {LockFileWithChildProcess} from './locking/lock_file_with_child_process';
import {SyncLocker} from './locking/sync_locker';
import {Logger} from './logging/logger';
import {AsyncNgccOptions, getSharedSetup, NgccOptions, SyncNgccOptions} from './ngcc_options';
import {AsyncNgccOptions, getSharedSetup, SyncNgccOptions} from './ngcc_options';
import {NgccConfiguration} from './packages/configuration';
import {EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES} from './packages/entry_point';
import {EntryPointManifest, InvalidatingEntryPointManifest} from './packages/entry_point_manifest';
@ -48,9 +48,9 @@ import {DirectPackageJsonUpdater, PackageJsonUpdater} from './writing/package_js
*
* @param options The options telling ngcc what to compile and how.
*/
export function mainNgcc(options: AsyncNgccOptions): Promise<void>;
export function mainNgcc(options: SyncNgccOptions): void;
export function mainNgcc(options: NgccOptions): void|Promise<void> {
export function mainNgcc<T extends AsyncNgccOptions|SyncNgccOptions>(options: T):
T extends AsyncNgccOptions ? Promise<void>: void;
export function mainNgcc(options: AsyncNgccOptions|SyncNgccOptions): void|Promise<void> {
const {
basePath,
targetEntryPointPath,

View File

@ -27,7 +27,7 @@
"peerDependencies": {
"@angular/compiler": "0.0.0-PLACEHOLDER",
"tslib": "^1.10.0",
"typescript": ">=3.8 <3.9"
"typescript": ">=3.8 <4.0"
},
"engines": {
"node": ">=10.0"
@ -52,4 +52,4 @@
"publishConfig": {
"registry": "https://wombat-dressing-room.appspot.com"
}
}
}

View File

@ -19,7 +19,7 @@ const MIN_TS_VERSION = '3.8.3';
* ∀ supported typescript version v, v < MAX_TS_VERSION
* MAX_TS_VERSION is not considered as a supported TypeScript version
*/
const MAX_TS_VERSION = '3.9.0';
const MAX_TS_VERSION = '4.0.0';
/**
* The currently used version of TypeScript, which can be adjusted for testing purposes using

View File

@ -142,21 +142,24 @@ describe('compiler compliance: providers', () => {
const result = compile(files, angularFiles);
expectEmit(
result.source, `
export class MyComponent {
}
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
MyComponent.ɵcmp = i0.ɵɵdefineComponent({
type: MyComponent,
selectors: [["my-component"]],
decls: 1,
vars: 0,
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
i0.ɵɵelement(0, "div");
}
},
encapsulation: 2
});`,
let MyComponent = /** @class */ (() => {
class MyComponent {
}
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
MyComponent.ɵcmp = i0.ɵɵdefineComponent({
type: MyComponent,
selectors: [["my-component"]],
decls: 1,
vars: 0,
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
i0.ɵɵelement(0, "div");
}
},
encapsulation: 2
});
return MyComponent;
})();`,
'Incorrect features');
});
});

View File

@ -135,7 +135,7 @@ describe('ngc transformer command-line', () => {
const exitCode = main(['-p', basePath], errorSpy);
const errorText = stripAnsi(errorSpy.calls.mostRecent().args[0]);
expect(errorText).toContain(
`test.ts:1:23 - error TS2307: Cannot find module './not-exist-deps'.` +
`test.ts:1:23 - error TS2307: Cannot find module './not-exist-deps' or its corresponding type declarations.` +
'\n');
expect(exitCode).toEqual(1);
});

View File

@ -391,11 +391,11 @@ runInEachFileSystem(os => {
});
/**
* The following set of tests verify that after Tsickle run we do not have cases which
* trigger automatic semicolon insertion, which breaks the code. In order to avoid the
* problem, we wrap all function expressions in certain fields ("providers" and
* "viewProviders") in parentheses. More info on Tsickle processing related to this case can
* be found here:
* The following set of tests verify that after Tsickle run we do not have cases
* which trigger automatic semicolon insertion, which breaks the code. In order
* to avoid the problem, we wrap all function expressions in certain fields
* ("providers" and "viewProviders") in parentheses. More info on Tsickle
* processing related to this case can be found here:
* https://github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts#L1021
*/
describe('wrap functions in certain fields in parentheses', () => {
@ -422,8 +422,9 @@ runInEachFileSystem(os => {
`;
const verifyOutput = (jsContents: string) => {
// verify that there is no pattern that triggers automatic semicolon insertion
// by checking that there are no return statements not wrapped in parentheses
// verify that there is no pattern that triggers automatic semicolon
// insertion by checking that there are no return statements not wrapped in
// parentheses
expect(trim(jsContents)).not.toContain(trim(`
return /**
* @return {?}
@ -1119,7 +1120,7 @@ runInEachFileSystem(os => {
.toContain(
'i0.ɵɵdefineInjector({ factory: function TestModule_Factory(t) ' +
'{ return new (t || TestModule)(); }, imports: [[OtherModule, RouterModule.forRoot()],' +
'\n OtherModule,\n RouterModule] });');
' OtherModule, RouterModule] });');
});
it('should compile NgModules with services without errors', () => {
@ -2018,7 +2019,8 @@ runInEachFileSystem(os => {
expect(dtsContents).toContain('PipeDefWithMeta<TestPipe');
expect(dtsContents).toContain('ɵɵNgModuleDefWithMeta<TestNgModule');
// Validate that each class's .d.ts declaration also has an injectable definition.
// Validate that each class's .d.ts declaration also has an injectable
// definition.
expect(dtsContents).toContain('InjectableDef<TestCmp');
expect(dtsContents).toContain('InjectableDef<TestDir');
expect(dtsContents).toContain('InjectableDef<TestPipe');
@ -2845,8 +2847,9 @@ runInEachFileSystem(os => {
expect(jsContents).toMatch(contentQueryRegExp('\\w+', true, 'TemplateRef'));
// match `i0.ɵɵviewQuery(_c2, true)`
// Note that while ViewQuery doesn't necessarily make sense on a directive, because it doesn't
// have a view, we still need to handle it because a component could extend the directive.
// Note that while ViewQuery doesn't necessarily make sense on a directive,
// because it doesn't have a view, we still need to handle it because a component
// could extend the directive.
expect(jsContents).toMatch(viewQueryRegExp('\\w+', true));
});
@ -3317,7 +3320,8 @@ runInEachFileSystem(os => {
class FooCmp {}`);
env.driveMain();
const jsContents = env.getContents('test.js');
// Note that the colon would only be there if there is an id attached to the string.
// Note that the colon would only be there if there is an id attached to the
// string.
expect(jsContents).not.toContain(':Some text');
});
@ -3679,7 +3683,7 @@ runInEachFileSystem(os => {
env.write('test.ts', `/** I am a top-level comment. */
import {NgModule} from '@angular/core';
@NgModule({})
export class TestModule {}
`);
@ -4437,10 +4441,11 @@ runInEachFileSystem(os => {
});
it('should compile programs with typeRoots', () => {
// Write out a custom tsconfig.json that includes 'typeRoots' and 'files'. 'files' is
// necessary because otherwise TS picks up the testTypeRoot/test/index.d.ts file into the
// program automatically. Shims are also turned on because the shim ts.CompilerHost wrapper
// can break typeRoot functionality (which this test is meant to detect).
// Write out a custom tsconfig.json that includes 'typeRoots' and 'files'. 'files'
// is necessary because otherwise TS picks up the testTypeRoot/test/index.d.ts
// file into the program automatically. Shims are also turned on because the shim
// ts.CompilerHost wrapper can break typeRoot functionality (which this test is
// meant to detect).
env.write('tsconfig.json', `{
"extends": "./tsconfig-base.json",
"angularCompilerOptions": {
@ -4613,8 +4618,9 @@ runInEachFileSystem(os => {
});
});
// Run checks that are present in preanalysis phase in both sync and async mode, to make sure
// the error messages are consistently thrown from `analyzeSync` and `analyzeAsync` functions.
// Run checks that are present in preanalysis phase in both sync and async mode, to
// make sure the error messages are consistently thrown from `analyzeSync` and
// `analyzeAsync` functions.
['sync', 'async'].forEach(mode => {
describe(`preanalysis phase checks [${mode}]`, () => {
let driveDiagnostics: () => Promise<ReadonlyArray<ts.Diagnostic>>;
@ -5278,7 +5284,7 @@ runInEachFileSystem(os => {
});
env.write(`test.ts`, `
import {Component} from '@angular/core';
@Component({
template: '<div class="test"></div>',
})
@ -6172,8 +6178,8 @@ export const Foo = Foo__PRE_R3__;
}
`);
// The application imports BetaModule from beta, gaining visibility of ExternalDir from
// alpha.
// The application imports BetaModule from beta, gaining visibility of
// ExternalDir from alpha.
env.write('test.ts', `
import {Component, NgModule} from '@angular/core';
import {BetaModule} from './beta';
@ -7000,4 +7006,4 @@ export const Foo = Foo__PRE_R3__;
function normalize(input: string): string {
return input.replace(/\s+/g, ' ').trim();
}
});
});