feat: add TypeScript 3 support (#25275)

PR Close #25275
This commit is contained in:
Alan Agius 2018-08-05 17:31:27 +02:00 committed by Matias Niemelä
parent c230173716
commit 5653fada32
30 changed files with 219 additions and 86 deletions

View File

@ -0,0 +1,49 @@
/**
* @license
* Copyright Google Inc. 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 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 http from '@angular/http';
import * as httpTesting from '@angular/http/testing';
import * as platformBrowser from '@angular/platform-browser';
import * as platformBrowserTesting from '@angular/platform-browser/testing';
import * as platformBrowserDynamic from '@angular/platform-browser-dynamic';
import * as platformServer from '@angular/platform-server';
import * as platformServerTesting from '@angular/platform-server/testing';
import * as platformWebworker from '@angular/platform-webworker';
import * as platformWebworkerDynamic from '@angular/platform-webworker-dynamic';
import * as router from '@angular/router';
import * as routerTesting from '@angular/router/testing';
import * as serviceWorker from '@angular/service-worker';
import * as upgrade from '@angular/upgrade';
export default {
compiler,
compilerTesting,
core,
coreTesting,
elements,
forms,
http,
httpTesting,
platformBrowser,
platformBrowserTesting,
platformBrowserDynamic,
platformServer,
platformServerTesting,
platformWebworker,
platformWebworkerDynamic,
router,
routerTesting,
serviceWorker,
upgrade,
};

View File

@ -0,0 +1,31 @@
{
"name": "angular-integration",
"description": "Assert that users with TypeScript 3.0 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/http": "file:../../dist/packages-dist/http",
"@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/platform-webworker": "file:../../dist/packages-dist/platform-webworker",
"@angular/platform-webworker-dynamic": "file:../../dist/packages-dist/platform-webworker-dynamic",
"@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": "2.5.41",
"rxjs": "file:../../node_modules/rxjs",
"typescript": "3.0.x",
"zone.js": "file:../../node_modules/zone.js"
},
"scripts": {
"test": "tsc"
}
}

View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../../dist/typings_test_ts30/",
"rootDir": ".",
"target": "es5",
"lib": [
"es5",
"dom",
"es2015.collection",
"es2015.iterable",
"es2015.promise"
],
"types": [],
"strictNullChecks": true
},
"files": [
"include-all.ts",
"node_modules/@types/jasmine/index.d.ts"
]
}

View File

@ -124,7 +124,7 @@
"tslint": "5.7.0",
"tslint-eslint-rules": "4.1.1",
"tsutils": "2.20.0",
"typescript": "2.9.x",
"typescript": "~3.0.1",
"uglify-es": "^3.3.9",
"universal-analytics": "0.4.15",
"vlq": "0.2.2",

View File

@ -11,7 +11,7 @@
},
"peerDependencies": {
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
"typescript": ">=2.7.2 <2.10"
"typescript": ">=3.0.1 <3.1"
},
"repository": {
"type": "git",

View File

@ -18,10 +18,10 @@ import {ConsoleReporter, Injector, MeasureValues, SampleDescription} from '../..
function createReporter(
{columnWidth = null, sampleId = null, descriptions = null, metrics = null}: {
columnWidth?: number,
sampleId?: string,
descriptions?: {[key: string]: any}[],
metrics?: {[key: string]: any}
columnWidth?: number | null,
sampleId?: string | null,
descriptions?: {[key: string]: any}[] | null,
metrics?: {[key: string]: any} | null
}) {
log = [];
if (!descriptions) {

View File

@ -314,7 +314,7 @@ export class HttpXhrBackend implements HttpBackend {
}
// Fire the request, and notify the event stream that it was fired.
xhr.send(reqBody);
xhr.send(reqBody !);
observer.next({type: HttpEventType.Sent});
// This is the return from the Observable function, which is the

View File

@ -19,8 +19,8 @@
"source-map": "^0.6.1"
},
"peerDependencies": {
"typescript": ">=2.7.2 <2.10",
"@angular/compiler": "0.0.0-PLACEHOLDER"
"@angular/compiler": "0.0.0-PLACEHOLDER",
"typescript": ">=3.0.1 <3.1"
},
"engines" : {
"node" : ">=8.0"

View File

@ -12,7 +12,8 @@ import {Evaluator, errorSymbol, recordMapEntry} from './evaluator';
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, InterfaceMetadata, METADATA_VERSION, MemberMetadata, MetadataEntry, MetadataError, MetadataMap, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleExportMetadata, ModuleMetadata, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataImportDefaultReference, isMetadataImportedSymbolReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMetadataSymbolicSelectExpression, isMethodMetadata} from './schema';
import {Symbols} from './symbols';
const isStatic = (node: ts.Node) => ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Static;
const isStatic = (node: ts.Declaration) =>
ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Static;
/**
* A set of collector options to use when collecting metadata.
@ -277,8 +278,8 @@ export class MetadataCollector {
}
});
const isExport = (node: ts.Node) =>
sourceFile.isDeclarationFile || ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export;
const isExport = (node: ts.Node) => sourceFile.isDeclarationFile ||
ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export;
const isExportedIdentifier = (identifier?: ts.Identifier) =>
identifier && exportMap.has(identifier.text);
const isExported =

View File

@ -224,7 +224,8 @@ function isEligibleForLowering(node: ts.Node | undefined): boolean {
return false;
case ts.SyntaxKind.VariableDeclaration:
// Avoid lowering expressions already in an exported variable declaration
return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) == 0;
return (ts.getCombinedModifierFlags(node as ts.VariableDeclaration) &
ts.ModifierFlags.Export) == 0;
}
return isEligibleForLowering(node.parent);
}
@ -370,7 +371,7 @@ function createExportTableFor(sourceFile: ts.SourceFile): Set<string> {
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.InterfaceDeclaration:
if ((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) != 0) {
if ((ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export) != 0) {
const classDeclaration =
node as(ts.ClassDeclaration | ts.FunctionDeclaration | ts.InterfaceDeclaration);
const name = classDeclaration.name;
@ -385,7 +386,7 @@ function createExportTableFor(sourceFile: ts.SourceFile): Set<string> {
break;
case ts.SyntaxKind.VariableDeclaration:
const variableDeclaration = node as ts.VariableDeclaration;
if ((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) != 0 &&
if ((ts.getCombinedModifierFlags(variableDeclaration) & ts.ModifierFlags.Export) != 0 &&
variableDeclaration.name.kind == ts.SyntaxKind.Identifier) {
const name = variableDeclaration.name as ts.Identifier;
exportTable.add(name.text);

View File

@ -102,14 +102,14 @@ const defaultEmitCallback: TsEmitCallback =
* Minimum supported TypeScript version
* supported typescript version v, v >= MIN_TS_VERSION
*/
const MIN_TS_VERSION = '2.7.2';
const MIN_TS_VERSION = '3.0.1';
/**
* Supremum of supported TypeScript versions
* supported typescript version v, v < MAX_TS_VERSION
* MAX_TS_VERSION is not considered as a supported TypeScript version
*/
const MAX_TS_VERSION = '2.10.0';
const MAX_TS_VERSION = '3.1.0';
class AngularCompilerProgram implements Program {
private rootNames: string[];

View File

@ -29,13 +29,13 @@ describe('expression diagnostics', () => {
registry = ts.createDocumentRegistry(false, '/src');
host = new MockLanguageServiceHost(['app/app.component.ts'], FILES, '/src');
service = ts.createLanguageService(host, registry);
const program = service.getProgram();
const program = service.getProgram() !;
const checker = program.getTypeChecker();
const options: CompilerOptions = Object.create(host.getCompilationSettings());
options.genDir = '/dist';
options.basePath = '/src';
const symbolResolverHost = new ReflectorHost(() => program, host, options);
context = new DiagnosticContext(service, program, checker, symbolResolverHost);
const symbolResolverHost = new ReflectorHost(() => program !, host, options);
context = new DiagnosticContext(service, program !, checker, symbolResolverHost);
type = context.getStaticSymbol('app/app.component.ts', 'AppComponent');
});

View File

@ -39,7 +39,7 @@ describe('symbol query', () => {
const host = new MockLanguageServiceHost(
['/quickstart/app/app.component.ts'], QUICKSTART, '/quickstart');
const service = ts.createLanguageService(host, registry);
program = service.getProgram();
program = service.getProgram() !;
checker = program.getTypeChecker();
sourceFile = program.getSourceFile('/quickstart/app/app.component.ts') !;
const options: CompilerOptions = Object.create(host.getCompilationSettings());

View File

@ -40,7 +40,7 @@ describe('Collector', () => {
'interface-reference.ts'
]);
service = ts.createLanguageService(host, documentRegistry);
program = service.getProgram();
program = service.getProgram() !;
collector = new MetadataCollector({quotedNames: true});
});
@ -1128,7 +1128,7 @@ describe('Collector', () => {
function override(fileName: string, content: string) {
host.overrideFile(fileName, content);
host.addFile(fileName);
program = service.getProgram();
program = service.getProgram() !;
}
function collectSource(content: string): ModuleMetadata {

View File

@ -29,7 +29,7 @@ describe('Evaluator', () => {
'newExpression.ts', 'errors.ts', 'declared.ts'
]);
service = ts.createLanguageService(host, documentRegistry);
program = service.getProgram();
program = service.getProgram() !;
typeChecker = program.getTypeChecker();
symbols = new Symbols(null as any as ts.SourceFile);
evaluator = new Evaluator(symbols, new Map());

View File

@ -42,7 +42,7 @@ describe('Symbols', () => {
beforeEach(() => {
host = new Host(FILES, ['consts.ts', 'expressions.ts', 'imports.ts']);
service = ts.createLanguageService(host);
program = service.getProgram();
program = service.getProgram() !;
expressions = program.getSourceFile('expressions.ts') !;
imports = program.getSourceFile('imports.ts') !;
});

View File

@ -7,6 +7,7 @@
*/
import * as fs from 'fs';
import * as path from 'path';
import * as ts from 'typescript';
export interface Directory { [name: string]: (Directory|string); }
@ -54,8 +55,10 @@ export class Host implements ts.LanguageServiceHost {
if (this.overrides.has(fileName)) {
return this.overrides.get(fileName);
}
if (fileName.endsWith('lib.d.ts')) {
return fs.readFileSync(ts.getDefaultLibFilePath(this.getCompilationSettings()), 'utf8');
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');
}
const current = open(this.directory, fileName);
if (typeof current === 'string') return current;
@ -76,6 +79,9 @@ export function open(directory: Directory, fileName: string): Directory|string|u
}
export class MockNode implements ts.Node {
decorators?: ts.NodeArray<ts.Decorator>;
modifiers?: ts.NodeArray<ts.Modifier>;
parent !: ts.Node;
constructor(
public kind: ts.SyntaxKind = ts.SyntaxKind.Identifier, public flags: ts.NodeFlags = 0,
public pos: number = 0, public end: number = 0) {}
@ -101,6 +107,11 @@ export class MockNode implements ts.Node {
}
export class MockIdentifier extends MockNode implements ts.Identifier {
originalKeywordKind?: ts.SyntaxKind;
isInJSDocNamespace?: boolean;
decorators?: ts.NodeArray<ts.Decorator>;
modifiers?: ts.NodeArray<ts.Modifier>;
parent !: ts.Node;
public text: string;
// TODO(issue/24571): remove '!'.
public escapedText !: ts.__String;
@ -124,6 +135,12 @@ export class MockIdentifier extends MockNode implements ts.Identifier {
}
export class MockVariableDeclaration extends MockNode implements ts.VariableDeclaration {
parent !: ts.VariableDeclarationList | ts.CatchClause;
exclamationToken?: ts.Token<ts.SyntaxKind.ExclamationToken>;
type?: ts.TypeNode;
initializer?: ts.Expression;
decorators?: ts.NodeArray<ts.Decorator>;
modifiers?: ts.NodeArray<ts.Modifier>;
// tslint:disable-next-line
public _declarationBrand: any;
@ -140,6 +157,11 @@ export class MockVariableDeclaration extends MockNode implements ts.VariableDecl
}
export class MockSymbol implements ts.Symbol {
declarations !: ts.Declaration[];
valueDeclaration !: ts.Declaration;
members?: ts.UnderscoreEscapedMap<ts.Symbol>;
exports?: ts.UnderscoreEscapedMap<ts.Symbol>;
globalExports?: ts.UnderscoreEscapedMap<ts.Symbol>;
// TODO(issue/24571): remove '!'.
public escapedName !: ts.__String;
constructor(

View File

@ -83,7 +83,7 @@ function createTestSupportFor(basePath: string) {
'lib': [
path.resolve(basePath, 'node_modules/typescript/lib/lib.es6.d.ts'),
],
...overrideOptions,
'paths': {'@angular/*': ['./node_modules/@angular/*']}, ...overrideOptions,
};
}

View File

@ -26,7 +26,7 @@ export class CompilerConfig {
defaultEncapsulation?: ViewEncapsulation,
useJit?: boolean,
jitDevMode?: boolean,
missingTranslation?: MissingTranslationStrategy,
missingTranslation?: MissingTranslationStrategy|null,
preserveWhitespaces?: boolean,
strictInjectionParameters?: boolean,
} = {}) {

View File

@ -1137,8 +1137,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
function createDir(
selector: string, {providers = null, viewProviders = null, deps = [], queries = []}: {
providers?: CompileProviderMetadata[],
viewProviders?: CompileProviderMetadata[],
providers?: CompileProviderMetadata[] | null,
viewProviders?: CompileProviderMetadata[] | null,
deps?: string[],
queries?: string[]
} = {}): CompileDirectiveSummary {

View File

@ -80,7 +80,7 @@ export class InertBodyHelper {
const xhr = new XMLHttpRequest();
xhr.responseType = 'document';
xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false);
xhr.send(null);
xhr.send(undefined);
const body: HTMLBodyElement = xhr.response.body;
body.removeChild(body.firstChild !);
return body;

View File

@ -27,7 +27,7 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
let oldLS: ts.LanguageService = info.languageService;
function tryCall<T>(fileName: string | undefined, callback: () => T): T {
if (fileName && !oldLS.getProgram().getSourceFile(fileName)) {
if (fileName && !oldLS.getProgram() !.getSourceFile(fileName)) {
return undefined as any as T;
}
try {
@ -84,10 +84,11 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
getCompletionsAtPosition: tryFilenameTwoCall(ls.getCompletionsAtPosition),
getCompletionEntryDetails: tryFilenameFiveCall(ls.getCompletionEntryDetails),
getCompletionEntrySymbol: tryFilenameThreeCall(ls.getCompletionEntrySymbol),
getJsxClosingTagAtPosition: tryFilenameOneCall(ls.getJsxClosingTagAtPosition),
getQuickInfoAtPosition: tryFilenameOneCall(ls.getQuickInfoAtPosition),
getNameOrDottedNameSpan: tryFilenameTwoCall(ls.getNameOrDottedNameSpan),
getBreakpointStatementAtPosition: tryFilenameOneCall(ls.getBreakpointStatementAtPosition),
getSignatureHelpItems: tryFilenameOneCall(ls.getSignatureHelpItems),
getSignatureHelpItems: tryFilenameTwoCall(ls.getSignatureHelpItems),
getRenameInfo: tryFilenameOneCall(ls.getRenameInfo),
findRenameLocations: tryFilenameThreeCall(ls.findRenameLocations),
getDefinitionAtPosition: tryFilenameOneCall(ls.getDefinitionAtPosition),
@ -229,32 +230,33 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
return base;
};
proxy.getQuickInfoAtPosition = function(fileName: string, position: number): ts.QuickInfo {
let base = oldLS.getQuickInfoAtPosition(fileName, position);
// TODO(vicb): the tags property has been removed in TS 2.2
tryOperation('get quick info', () => {
const ours = ls.getHoverAt(fileName, position);
if (ours) {
const displayParts: ts.SymbolDisplayPart[] = [];
for (const part of ours.text) {
displayParts.push({kind: part.language || 'angular', text: part.text});
}
const tags = base && (<any>base).tags;
base = <any>{
displayParts,
documentation: [],
kind: 'angular',
kindModifiers: 'what does this do?',
textSpan: {start: ours.span.start, length: ours.span.end - ours.span.start},
};
if (tags) {
(<any>base).tags = tags;
}
}
});
proxy.getQuickInfoAtPosition = function(fileName: string, position: number): ts.QuickInfo |
undefined {
let base = oldLS.getQuickInfoAtPosition(fileName, position);
// TODO(vicb): the tags property has been removed in TS 2.2
tryOperation('get quick info', () => {
const ours = ls.getHoverAt(fileName, position);
if (ours) {
const displayParts: ts.SymbolDisplayPart[] = [];
for (const part of ours.text) {
displayParts.push({kind: part.language || 'angular', text: part.text});
}
const tags = base && (<any>base).tags;
base = <any>{
displayParts,
documentation: [],
kind: 'angular',
kindModifiers: 'what does this do?',
textSpan: {start: ours.span.start, length: ours.span.end - ours.span.start},
};
if (tags) {
(<any>base).tags = tags;
}
}
});
return base;
};
return base;
};
proxy.getSemanticDiagnostics = function(fileName: string) {
let result = oldLS.getSemanticDiagnostics(fileName);
@ -263,7 +265,7 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
info.project.projectService.logger.info(`Computing Angular semantic diagnostics...`);
const ours = ls.getDiagnostics(fileName);
if (ours && ours.length) {
const file = oldLS.getProgram().getSourceFile(fileName);
const file = oldLS.getProgram() !.getSourceFile(fileName);
if (file) {
base.push.apply(base, ours.map(d => diagnosticToDiagnostic(d, file)));
}

View File

@ -166,7 +166,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
};
} else {
const analyzeHost = {isSourceFile(filePath: string) { return true; }};
const programFiles = this.program.getSourceFiles().map(sf => sf.fileName);
const programFiles = this.program !.getSourceFiles().map(sf => sf.fileName);
analyzedModules =
analyzeNgModules(programFiles, analyzeHost, this.staticSymbolResolver, this.resolver);
}
@ -224,7 +224,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
}
getSourceFile(fileName: string): ts.SourceFile|undefined {
return this.tsService.getProgram().getSourceFile(fileName);
return this.tsService.getProgram() !.getSourceFile(fileName);
}
updateAnalyzedModules() {
@ -244,7 +244,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private get checker() {
let checker = this._checker;
if (!checker) {
checker = this._checker = this.program.getTypeChecker();
checker = this._checker = this.program !.getTypeChecker();
}
return checker;
}
@ -257,7 +257,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
this._staticSymbolResolver.invalidateFile(fileName);
this.clearCaches();
const seen = new Set<string>();
for (let sourceFile of this.program.getSourceFiles()) {
for (let sourceFile of this.program !.getSourceFiles()) {
const fileName = sourceFile.fileName;
seen.add(fileName);
const version = this.host.getScriptVersion(fileName);
@ -325,14 +325,14 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
span,
type,
get members() {
return getClassMembersFromDeclaration(t.program, t.checker, sourceFile, declaration);
return getClassMembersFromDeclaration(t.program !, t.checker, sourceFile, declaration);
},
get query() {
if (!queryCache) {
const pipes = t.service.getPipesAt(fileName, node.getStart());
queryCache = getSymbolQuery(
t.program, t.checker, sourceFile,
() => getPipesTable(sourceFile, t.program, t.checker, pipes));
t.program !, t.checker, sourceFile,
() => getPipesTable(sourceFile, t.program !, t.checker, pipes));
}
return queryCache;
}
@ -394,7 +394,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
// The host's getCurrentDirectory() is not reliable as it is always "" in
// tsserver. We don't need the exact base directory, just one that contains
// a source file.
const source = this.tsService.getProgram().getSourceFile(this.context);
const source = this.tsService.getProgram() !.getSourceFile(this.context);
if (!source) {
throw new Error('Internal error: no context could be determined');
}
@ -410,7 +410,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
options.paths = compilerOptions.paths;
}
result = this._reflectorHost =
new ReflectorHost(() => this.tsService.getProgram(), this.host, options);
new ReflectorHost(() => this.tsService.getProgram() !, this.host, options);
}
return result;
}

View File

@ -26,7 +26,7 @@ describe('references', () => {
beforeEach(() => {
mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], toh);
service = ts.createLanguageService(mockHost, documentRegistry);
program = service.getProgram();
program = service.getProgram() !;
ngHost = new TypeScriptServiceHost(mockHost, service);
ngService = createLanguageService(ngHost);
ngHost.setSite(ngService);

View File

@ -25,7 +25,7 @@ describe('plugin', () => {
it('should not report errors on tour of heroes', () => {
expectNoDiagnostics(service.getCompilerOptionsDiagnostics());
for (let source of program.getSourceFiles()) {
for (let source of program !.getSourceFiles()) {
expectNoDiagnostics(service.getSyntacticDiagnostics(source.fileName));
expectNoDiagnostics(service.getSemanticDiagnostics(source.fileName));
}
@ -36,7 +36,7 @@ describe('plugin', () => {
{ts: ts, languageService: service, project: mockProject, languageServiceHost: mockHost});
it('should not report template errors on tour of heroes', () => {
for (let source of program.getSourceFiles()) {
for (let source of program !.getSourceFiles()) {
// Ignore all 'cases.ts' files as they intentionally contain errors.
if (!source.fileName.endsWith('cases.ts')) {
expectNoDiagnostics(plugin.getSemanticDiagnostics(source.fileName));
@ -204,12 +204,12 @@ describe('plugin', () => {
function contains(fileName: string, locationMarker: string, ...names: string[]) {
const location = getMarkerLocation(fileName, locationMarker);
expectEntries(
locationMarker, plugin.getCompletionsAtPosition(fileName, location, undefined), ...names);
locationMarker, plugin.getCompletionsAtPosition(fileName, location, undefined) !, ...names);
}
function expectEmpty(fileName: string, locationMarker: string) {
const location = getMarkerLocation(fileName, locationMarker);
expect(plugin.getCompletionsAtPosition(fileName, location, undefined).entries || []).toEqual([
expect(plugin.getCompletionsAtPosition(fileName, location, undefined) !.entries || []).toEqual([
]);
}

View File

@ -7,6 +7,7 @@
*/
export class MockBody implements Body {
readonly body !: ReadableStream;
bodyUsed: boolean = false;
constructor(public _body: string|null) {}
@ -80,6 +81,9 @@ export class MockHeaders implements Headers {
}
export class MockRequest extends MockBody implements Request {
readonly isHistoryNavigation: boolean = false;
readonly isReloadNavigation: boolean = false;
readonly body !: ReadableStream;
readonly cache: RequestCache = 'default';
readonly credentials: RequestCredentials = 'omit';
readonly destination: RequestDestination = 'document';
@ -91,7 +95,6 @@ export class MockRequest extends MockBody implements Request {
readonly redirect: RequestRedirect = 'error';
readonly referrer: string = '';
readonly referrerPolicy: ReferrerPolicy = 'no-referrer';
readonly type: RequestType = '';
readonly signal: AbortSignal = null as any;
url: string;
@ -132,13 +135,13 @@ export class MockRequest extends MockBody implements Request {
}
export class MockResponse extends MockBody implements Response {
readonly trailer: Promise<Headers> = Promise.resolve(new MockHeaders());
readonly headers: Headers = new MockHeaders();
get ok(): boolean { return this.status >= 200 && this.status < 300; }
readonly status: number;
readonly statusText: string;
readonly type: ResponseType = 'basic';
readonly url: string = '';
readonly body: ReadableStream|null = null;
readonly redirected: boolean = false;
constructor(

View File

@ -550,7 +550,7 @@ export declare class NgZone {
readonly onStable: EventEmitter<any>;
readonly onUnstable: EventEmitter<any>;
constructor({ enableLongStackTrace }: {
enableLongStackTrace?: boolean;
enableLongStackTrace?: boolean | undefined;
});
run<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T;
runGuarded<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T;

View File

@ -11,7 +11,7 @@
"test": "test"
},
"peerDependencies": {
"typescript": "^2.6.1"
"typescript": "^3.0.1"
},
"dependencies": {
"chalk": "^2.3.1",
@ -21,7 +21,7 @@
"devDependencies": {
"chai": "^4.1.2",
"jasmine": "^3.1.0",
"typescript": "~2.6.2"
"typescript": "~3.0.1"
},
"repository": {},
"keywords": [

View File

@ -153,9 +153,9 @@ type-detect@^4.0.0:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
typescript@~2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4"
typescript@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1.tgz#43738f29585d3a87575520a4b93ab6026ef11fdb"
wrappy@1:
version "1.0.2"

View File

@ -7079,14 +7079,14 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
typescript@2.9.x:
version "2.9.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
"typescript@>=2.6.2 <2.8":
version "2.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"
typescript@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/npm/OBG-NPM/typescript/-/typescript-3.0.1.tgz#43738f29585d3a87575520a4b93ab6026ef11fdb"
uglify-es@^3.3.9:
version "3.3.9"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"