Merge branch 'master' into checkJSFiles

This commit is contained in:
Mohamed Hegazy
2017-03-27 10:46:40 -07:00
26 changed files with 389 additions and 40 deletions
+20 -18
View File
@@ -8277,8 +8277,8 @@ namespace ts {
maybeStack[depth].set(id, RelationComparisonResult.Succeeded);
depth++;
const saveExpandingFlags = expandingFlags;
if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth)) expandingFlags |= 1;
if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth)) expandingFlags |= 2;
if (!(expandingFlags & 1) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= 1;
if (!(expandingFlags & 2) && isDeeplyNestedType(target, targetStack, depth)) expandingFlags |= 2;
let result: Ternary;
if (expandingFlags === 3) {
result = Ternary.Maybe;
@@ -8698,21 +8698,23 @@ namespace ts {
return false;
}
// Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case
// when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible,
// though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding.
// Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at
// some level beyond that.
function isDeeplyNestedGeneric(type: Type, stack: Type[], depth: number): boolean {
// We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
if (getObjectFlags(type) & (ObjectFlags.Reference | ObjectFlags.Instantiated) && depth >= 5) {
// Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
// for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
// though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
// expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5
// levels, but unequal at some level beyond that.
function isDeeplyNestedType(type: Type, stack: Type[], depth: number): boolean {
// We track all object types that have an associated symbol (representing the origin of the type)
if (depth >= 5 && type.flags & TypeFlags.Object) {
const symbol = type.symbol;
let count = 0;
for (let i = 0; i < depth; i++) {
const t = stack[i];
if (getObjectFlags(t) & (ObjectFlags.Reference | ObjectFlags.Instantiated) && t.symbol === symbol) {
count++;
if (count >= 5) return true;
if (symbol) {
let count = 0;
for (let i = 0; i < depth; i++) {
const t = stack[i];
if (t.flags & TypeFlags.Object && t.symbol === symbol) {
count++;
if (count >= 5) return true;
}
}
}
}
@@ -9455,7 +9457,7 @@ namespace ts {
if (isInProcess(source, target)) {
return;
}
if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
if (isDeeplyNestedType(source, sourceStack, depth) && isDeeplyNestedType(target, targetStack, depth)) {
return;
}
const key = source.id + "," + target.id;
@@ -18788,7 +18790,7 @@ namespace ts {
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive)) {
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
-1
View File
@@ -3019,7 +3019,6 @@ namespace ts {
ObjectLiteral = 1 << 7, // Originates in an object literal
EvolvingArray = 1 << 8, // Evolving array type
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
NonPrimitive = 1 << 10, // NonPrimitive object type
ClassOrInterface = Class | Interface
}
@@ -1007,6 +1007,41 @@ namespace ts.projectSystem {
checkProjectRootFiles(projectService.configuredProjects[0], [commonFile1.path, commonFile2.path]);
});
it("should disable features when the files are too large", () => {
const file1 = {
path: "/a/b/f1.js",
content: "let x =1;",
fileSize: 10 * 1024 * 1024
};
const file2 = {
path: "/a/b/f2.js",
content: "let y =1;",
fileSize: 6 * 1024 * 1024
};
const file3 = {
path: "/a/b/f3.js",
content: "let y =1;",
fileSize: 6 * 1024 * 1024
};
const proj1name = "proj1", proj2name = "proj2", proj3name = "proj3";
const host = createServerHost([file1, file2, file3]);
const projectService = createProjectService(host);
projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name });
const proj1 = projectService.findProject(proj1name);
assert.isTrue(proj1.languageServiceEnabled);
projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name });
const proj2 = projectService.findProject(proj2name);
assert.isTrue(proj2.languageServiceEnabled);
projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name });
const proj3 = projectService.findProject(proj3name);
assert.isFalse(proj3.languageServiceEnabled);
});
it("should use only one inferred project if 'useOneInferredProject' is set", () => {
const file1 = {
path: "/a/b/main.ts",
+33 -8
View File
@@ -1396,6 +1396,7 @@ interface AudioNode extends EventTarget {
readonly numberOfInputs: number;
readonly numberOfOutputs: number;
connect(destination: AudioNode, output?: number, input?: number): AudioNode;
connect(destination: AudioParam, output?: number): void;
disconnect(output?: number): void;
disconnect(destination: AudioNode, output?: number, input?: number): void;
disconnect(destination: AudioParam, output?: number): void;
@@ -2152,7 +2153,9 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods {
createPattern(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, repetition: string): CanvasPattern;
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
drawFocusIfNeeded(element: Element): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, offsetX: number, offsetY: number, width?: number, height?: number, canvasOffsetX?: number, canvasOffsetY?: number, canvasImageWidth?: number, canvasImageHeight?: number): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number, dstW: number, dstH: number): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, srcX: number, srcY: number, srcW: number, srcH: number, dstX: number, dstY: number, dstW: number, dstH: number): void;
fill(fillRule?: string): void;
fillRect(x: number, y: number, w: number, h: number): void;
fillText(text: string, x: number, y: number, maxWidth?: number): void;
@@ -2449,10 +2452,10 @@ declare var DOMException: {
}
interface DOMImplementation {
createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType): Document;
createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType | null): Document;
createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType;
createHTMLDocument(title: string): Document;
hasFeature(): boolean;
hasFeature(feature: string | null, version: string | null): boolean;
}
declare var DOMImplementation: {
@@ -3449,6 +3452,7 @@ declare var Document: {
}
interface DocumentFragment extends Node, NodeSelector, ParentNode {
getElementById(elementId: string): HTMLElement | null;
}
declare var DocumentFragment: {
@@ -11837,7 +11841,7 @@ interface URL {
protocol: string;
search: string;
username: string;
readonly searchparams: URLSearchParams;
readonly searchParams: URLSearchParams;
toString(): string;
}
@@ -12161,12 +12165,12 @@ interface WebGLRenderingContext {
stencilMaskSeparate(face: number, mask: number): void;
stencilOp(fail: number, zfail: number, zpass: number): void;
stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void;
texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels?: ArrayBufferView): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
texParameterf(target: number, pname: number, param: number): void;
texParameteri(target: number, pname: number, param: number): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels?: ArrayBufferView): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView | null): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
uniform1f(location: WebGLUniformLocation | null, x: number): void;
uniform1fv(location: WebGLUniformLocation, v: Float32Array | number[]): void;
uniform1i(location: WebGLUniformLocation | null, x: number): void;
@@ -13260,6 +13264,8 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint;
webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint;
webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
scroll(options?: ScrollToOptions): void;
scrollTo(options?: ScrollToOptions): void;
scrollBy(options?: ScrollToOptions): void;
@@ -13473,6 +13479,7 @@ interface Body {
blob(): Promise<Blob>;
json(): Promise<any>;
text(): Promise<string>;
formData(): Promise<FormData>;
}
interface CanvasPathMethods {
@@ -13835,6 +13842,21 @@ interface Canvas2DContextAttributes {
[attribute: string]: boolean | string | undefined;
}
interface ImageBitmapOptions {
imageOrientation?: "none" | "flipY";
premultiplyAlpha?: "none" | "premultiply" | "default";
colorSpaceConversion?: "none" | "default";
resizeWidth?: number;
resizeHeight?: number;
resizeQuality?: "pixelated" | "low" | "medium" | "high";
}
interface ImageBitmap {
readonly width: number;
readonly height: number;
close(): void;
}
interface URLSearchParams {
/**
* Appends a specified key/value pair as a new search parameter.
@@ -13879,6 +13901,7 @@ interface NodeListOf<TNode extends Node> extends NodeList {
interface HTMLCollectionOf<T extends Element> extends HTMLCollection {
item(index: number): T;
namedItem(name: string): T;
[index: number]: T;
}
interface BlobPropertyBag {
@@ -14840,6 +14863,8 @@ declare function webkitCancelAnimationFrame(handle: number): void;
declare function webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint;
declare function webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint;
declare function webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
declare function createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function scroll(options?: ScrollToOptions): void;
declare function scrollTo(options?: ScrollToOptions): void;
declare function scrollBy(options?: ScrollToOptions): void;
+41 -1
View File
@@ -1,4 +1,29 @@
interface GeneratorFunction extends Function { }
interface Generator extends Iterator<any> { }
interface GeneratorFunction {
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
new (...args: any[]): Generator;
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
(...args: any[]): Generator;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: Generator;
}
interface GeneratorFunctionConstructor {
/**
@@ -6,7 +31,22 @@ interface GeneratorFunctionConstructor {
* @param args A list of arguments the function accepts.
*/
new (...args: string[]): GeneratorFunction;
/**
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
(...args: string[]): GeneratorFunction;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: GeneratorFunction;
}
declare var GeneratorFunction: GeneratorFunctionConstructor;
+1 -1
View File
@@ -137,7 +137,7 @@ interface Function {
[Symbol.hasInstance](value: any): boolean;
}
interface GeneratorFunction extends Function {
interface GeneratorFunction {
readonly [Symbol.toStringTag]: "GeneratorFunction";
}
+19
View File
@@ -1407,6 +1407,8 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
readonly performance: Performance;
readonly self: WorkerGlobalScope;
msWriteProfilerMark(profilerMarkName: string): void;
createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -1467,6 +1469,21 @@ interface ErrorEventInit {
error?: any;
}
interface ImageBitmapOptions {
imageOrientation?: "none" | "flipY";
premultiplyAlpha?: "none" | "premultiply" | "default";
colorSpaceConversion?: "none" | "default";
resizeWidth?: number;
resizeHeight?: number;
resizeQuality?: "pixelated" | "low" | "medium" | "high";
}
interface ImageBitmap {
readonly width: number;
readonly height: number;
close(): void;
}
interface BlobPropertyBag {
type?: string;
endings?: string;
@@ -1697,6 +1714,8 @@ declare var onerror: (this: DedicatedWorkerGlobalScope, ev: ErrorEvent) => any;
declare var performance: Performance;
declare var self: WorkerGlobalScope;
declare function msWriteProfilerMark(profilerMarkName: string): void;
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function dispatchEvent(evt: Event): boolean;
declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare var indexedDB: IDBFactory;
+20 -5
View File
@@ -254,6 +254,7 @@ namespace ts.server {
private compilerOptionsForInferredProjects: CompilerOptions;
private compileOnSaveForInferredProjects: boolean;
private readonly projectToSizeMap: Map<number> = createMap<number>();
private readonly directoryWatchers: DirectoryWatchers;
private readonly throttledOperations: ThrottledOperations;
@@ -563,9 +564,11 @@ namespace ts.server {
switch (project.projectKind) {
case ProjectKind.External:
removeItemFromSet(this.externalProjects, <ExternalProject>project);
this.projectToSizeMap.delete((project as ExternalProject).externalProjectName);
break;
case ProjectKind.Configured:
removeItemFromSet(this.configuredProjects, <ConfiguredProject>project);
this.projectToSizeMap.delete((project as ConfiguredProject).canonicalConfigFilePath);
break;
case ProjectKind.Inferred:
removeItemFromSet(this.inferredProjects, <InferredProject>project);
@@ -852,10 +855,15 @@ namespace ts.server {
return { success: true, projectOptions, configFileErrors: errors };
}
private exceededTotalSizeLimitForNonTsFiles<T>(options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>) {
private exceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>) {
if (options && options.disableSizeLimit || !this.host.getFileSize) {
return false;
}
let availableSpace = maxProgramSizeForNonTsFiles;
this.projectToSizeMap.set(name, 0);
this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0)));
let totalNonTsFileSize = 0;
for (const f of fileNames) {
const fileName = propertyReader.getFileName(f);
@@ -864,9 +872,16 @@ namespace ts.server {
}
totalNonTsFileSize += this.host.getFileSize(fileName);
if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) {
// Keep the size as zero since it's disabled
return true;
}
}
if (totalNonTsFileSize > availableSpace) {
return true;
}
this.projectToSizeMap.set(name, totalNonTsFileSize);
return false;
}
@@ -877,7 +892,7 @@ namespace ts.server {
this,
this.documentRegistry,
compilerOptions,
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader),
options.compileOnSave === undefined ? true : options.compileOnSave);
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typeAcquisition, /*configFileErrors*/ undefined);
@@ -897,7 +912,7 @@ namespace ts.server {
}
private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) {
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const project = new ConfiguredProject(
configFileName,
this,
@@ -1050,7 +1065,7 @@ namespace ts.server {
return configFileErrors;
}
if (this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) {
if (this.exceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) {
project.setCompilerOptions(projectOptions.compilerOptions);
if (!project.languageServiceEnabled) {
// language service is already disabled
@@ -1414,7 +1429,7 @@ namespace ts.server {
if (externalProject) {
if (!tsConfigFiles) {
const compilerOptions = convertCompilerOptions(proj.options);
if (this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
externalProject.disableLanguageService();
}
else {
+1 -1
View File
@@ -1031,7 +1031,7 @@ namespace ts.server {
export class ExternalProject extends Project {
private typeAcquisition: TypeAcquisition;
constructor(externalProjectName: string,
constructor(public externalProjectName: string,
projectService: ProjectService,
documentRegistry: ts.DocumentRegistry,
compilerOptions: CompilerOptions,
+10 -4
View File
@@ -25,8 +25,14 @@ namespace ts.server {
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
}
function shouldSkipSematicCheck(project: Project) {
return (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject();
function shouldSkipSemanticCheck(project: Project) {
if (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) {
return project.isJsOnlyProject();
}
else {
// For configured projects, require that skipLibCheck be set also
return project.getCompilerOptions().skipLibCheck && project.isJsOnlyProject();
}
}
interface FileStart {
@@ -447,7 +453,7 @@ namespace ts.server {
private semanticCheck(file: NormalizedPath, project: Project) {
try {
let diags: Diagnostic[] = [];
if (!shouldSkipSematicCheck(project)) {
if (!shouldSkipSemanticCheck(project)) {
diags = project.getLanguageService().getSemanticDiagnostics(file);
}
@@ -555,7 +561,7 @@ namespace ts.server {
private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
const { project, file } = this.getFileAndProject(args);
if (isSemantic && shouldSkipSematicCheck(project)) {
if (isSemantic && shouldSkipSemanticCheck(project)) {
return [];
}
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
+1 -1
View File
@@ -419,7 +419,7 @@ namespace ts.SymbolDisplay {
if (!documentation) {
documentation = symbol.getDocumentationComment();
if (documentation.length === 0 && symbol.flags & SymbolFlags.Property) {
// For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo`
// For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
// there documentation comments might be attached to the right hand side symbol of their declarations.
// The pattern of such special property access is that the parent symbol is the symbol of the file.
if (symbol.parent && forEach(symbol.parent.declarations, declaration => declaration.kind === SyntaxKind.SourceFile)) {
@@ -0,0 +1,14 @@
//// [deeplyNestedCheck.ts]
// Repro from #14794
interface DataSnapshot<X = {}> {
child(path: string): DataSnapshot;
}
interface Snapshot<T> extends DataSnapshot {
child<U extends keyof T>(path: U): Snapshot<T[U]>;
}
//// [deeplyNestedCheck.js]
// Repro from #14794
@@ -0,0 +1,29 @@
=== tests/cases/compiler/deeplyNestedCheck.ts ===
// Repro from #14794
interface DataSnapshot<X = {}> {
>DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0))
>X : Symbol(X, Decl(deeplyNestedCheck.ts, 2, 23))
child(path: string): DataSnapshot;
>child : Symbol(DataSnapshot.child, Decl(deeplyNestedCheck.ts, 2, 32))
>path : Symbol(path, Decl(deeplyNestedCheck.ts, 3, 8))
>DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0))
}
interface Snapshot<T> extends DataSnapshot {
>Snapshot : Symbol(Snapshot, Decl(deeplyNestedCheck.ts, 4, 1))
>T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19))
>DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0))
child<U extends keyof T>(path: U): Snapshot<T[U]>;
>child : Symbol(Snapshot.child, Decl(deeplyNestedCheck.ts, 6, 44))
>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8))
>T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19))
>path : Symbol(path, Decl(deeplyNestedCheck.ts, 7, 27))
>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8))
>Snapshot : Symbol(Snapshot, Decl(deeplyNestedCheck.ts, 4, 1))
>T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19))
>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8))
}
@@ -0,0 +1,29 @@
=== tests/cases/compiler/deeplyNestedCheck.ts ===
// Repro from #14794
interface DataSnapshot<X = {}> {
>DataSnapshot : DataSnapshot<X>
>X : X
child(path: string): DataSnapshot;
>child : (path: string) => DataSnapshot<{}>
>path : string
>DataSnapshot : DataSnapshot<X>
}
interface Snapshot<T> extends DataSnapshot {
>Snapshot : Snapshot<T>
>T : T
>DataSnapshot : DataSnapshot<X>
child<U extends keyof T>(path: U): Snapshot<T[U]>;
>child : <U extends keyof T>(path: U) => Snapshot<T[U]>
>U : U
>T : T
>path : U
>U : U
>Snapshot : Snapshot<T>
>T : T
>U : U
}
@@ -0,0 +1,13 @@
//// [nonPrimitiveIndexingWithForIn.ts]
var a: object;
for (var key in a) {
var value = a[key];
}
//// [nonPrimitiveIndexingWithForIn.js]
var a;
for (var key in a) {
var value = a[key];
}
@@ -0,0 +1,14 @@
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts ===
var a: object;
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3))
for (var key in a) {
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForIn.ts, 2, 8))
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3))
var value = a[key];
>value : Symbol(value, Decl(nonPrimitiveIndexingWithForIn.ts, 3, 7))
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3))
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForIn.ts, 2, 8))
}
@@ -0,0 +1,15 @@
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts ===
var a: object;
>a : object
for (var key in a) {
>key : string
>a : object
var value = a[key];
>value : any
>a[key] : any
>a : object
>key : string
}
@@ -0,0 +1,12 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts(4,17): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts (1 errors) ====
var a: object;
for (var key in a) {
var value = a[key]; // error
~~~~~~
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
}
@@ -0,0 +1,13 @@
//// [nonPrimitiveIndexingWithForInNoImplicitAny.ts]
var a: object;
for (var key in a) {
var value = a[key]; // error
}
//// [nonPrimitiveIndexingWithForInNoImplicitAny.js]
var a;
for (var key in a) {
var value = a[key]; // error
}
@@ -0,0 +1,13 @@
//// [nonPrimitiveIndexingWithForInSupressError.ts]
var a: object;
for (var key in a) {
var value = a[key];
}
//// [nonPrimitiveIndexingWithForInSupressError.js]
var a;
for (var key in a) {
var value = a[key];
}
@@ -0,0 +1,14 @@
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts ===
var a: object;
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3))
for (var key in a) {
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 2, 8))
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3))
var value = a[key];
>value : Symbol(value, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 3, 7))
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3))
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 2, 8))
}
@@ -0,0 +1,15 @@
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts ===
var a: object;
>a : object
for (var key in a) {
>key : string
>a : object
var value = a[key];
>value : any
>a[key] : any
>a : object
>key : string
}
@@ -0,0 +1,9 @@
// Repro from #14794
interface DataSnapshot<X = {}> {
child(path: string): DataSnapshot;
}
interface Snapshot<T> extends DataSnapshot {
child<U extends keyof T>(path: U): Snapshot<T[U]>;
}
@@ -0,0 +1,5 @@
var a: object;
for (var key in a) {
var value = a[key];
}
@@ -0,0 +1,6 @@
// @noImplicitAny: true
var a: object;
for (var key in a) {
var value = a[key]; // error
}
@@ -0,0 +1,7 @@
// @noImplicitAny: true
// @suppressImplicitAnyIndexErrors: true
var a: object;
for (var key in a) {
var value = a[key];
}