Merge branch 'master' into watchImprovements

This commit is contained in:
Sheetal Nandi 2017-09-12 10:33:58 -07:00
commit aea8630ace
24 changed files with 40671 additions and 80 deletions

View File

@ -334,7 +334,8 @@ namespace ts {
let flowLoopStart = 0;
let flowLoopCount = 0;
let visitedFlowCount = 0;
let sharedFlowCount = 0;
let flowAnalysisDisabled = false;
const emptyStringType = getLiteralType("");
const zeroType = getLiteralType(0);
@ -352,8 +353,8 @@ namespace ts {
const flowLoopNodes: FlowNode[] = [];
const flowLoopKeys: string[] = [];
const flowLoopTypes: Type[][] = [];
const visitedFlowNodes: FlowNode[] = [];
const visitedFlowTypes: FlowType[] = [];
const sharedFlowNodes: FlowNode[] = [];
const sharedFlowTypes: FlowType[] = [];
const potentialThisCollisions: Node[] = [];
const potentialNewTargetCollisions: Node[] = [];
const awaitedTypeStack: number[] = [];
@ -10386,7 +10387,7 @@ namespace ts {
// results for union and intersection types for performance reasons.
function couldContainTypeVariables(type: Type): boolean {
const objectFlags = getObjectFlags(type);
return !!(type.flags & TypeFlags.TypeVariable ||
return !!(type.flags & (TypeFlags.TypeVariable | TypeFlags.Index) ||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
objectFlags & ObjectFlags.Mapped ||
@ -10554,6 +10555,13 @@ namespace ts {
inferFromTypes(sourceTypes[i], targetTypes[i]);
}
}
else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) {
inferFromTypes((<IndexType>source).type, (<IndexType>target).type);
}
else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) {
inferFromTypes((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType);
inferFromTypes((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType);
}
else if (target.flags & TypeFlags.UnionOrIntersection) {
const targetTypes = (<UnionOrIntersectionType>target).types;
let typeVariableCount = 0;
@ -10578,7 +10586,7 @@ namespace ts {
priority = savePriority;
}
}
else if (source.flags & TypeFlags.UnionOrIntersection) {
else if (source.flags & TypeFlags.Union) {
// Source is a union or intersection type, infer from each constituent type
const sourceTypes = (<UnionOrIntersectionType>source).types;
for (const sourceType of sourceTypes) {
@ -10587,7 +10595,7 @@ namespace ts {
}
else {
source = getApparentType(source);
if (source.flags & TypeFlags.Object) {
if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
const key = source.id + "," + target.id;
if (visited && visited.get(key)) {
return;
@ -10627,6 +10635,12 @@ namespace ts {
}
function inferFromObjectTypes(source: Type, target: Type) {
if (isGenericMappedType(source) && isGenericMappedType(target)) {
// The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
// from S to T and from X to Y.
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), getConstraintTypeFromMappedType(<MappedType>target));
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
}
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
if (constraintType.flags & TypeFlags.Index) {
@ -10667,7 +10681,7 @@ namespace ts {
function inferFromProperties(source: Type, target: Type) {
const properties = getPropertiesOfObjectType(target);
for (const targetProp of properties) {
const sourceProp = getPropertyOfObjectType(source, targetProp.escapedName);
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
if (sourceProp) {
inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
}
@ -11459,14 +11473,25 @@ namespace ts {
return false;
}
function reportFlowControlError(node: Node) {
const block = <Block | ModuleBlock | SourceFile>findAncestor(node, isFunctionOrModuleBlock);
const sourceFile = getSourceFileOfNode(node);
const span = getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
}
function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, couldBeUninitialized?: boolean) {
let key: string;
let flowDepth = 0;
if (flowAnalysisDisabled) {
return unknownType;
}
if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
return declaredType;
}
const visitedFlowStart = visitedFlowCount;
const sharedFlowStart = sharedFlowCount;
const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
visitedFlowCount = visitedFlowStart;
sharedFlowCount = sharedFlowStart;
// When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
// we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
// on empty arrays are possible without implicit any errors and new element types can be inferred without
@ -11478,60 +11503,70 @@ namespace ts {
return resultType;
function getTypeAtFlowNode(flow: FlowNode): FlowType {
if (flowDepth === 2500) {
// We have made 2500 recursive invocations. To avoid overflowing the call stack we report an error
// and disable further control flow analysis in the containing function or module body.
flowAnalysisDisabled = true;
reportFlowControlError(reference);
return unknownType;
}
flowDepth++;
while (true) {
if (flow.flags & FlowFlags.Shared) {
const flags = flow.flags;
if (flags & FlowFlags.Shared) {
// We cache results of flow type resolution for shared nodes that were previously visited in
// the same getFlowTypeOfReference invocation. A node is considered shared when it is the
// antecedent of more than one node.
for (let i = visitedFlowStart; i < visitedFlowCount; i++) {
if (visitedFlowNodes[i] === flow) {
return visitedFlowTypes[i];
for (let i = sharedFlowStart; i < sharedFlowCount; i++) {
if (sharedFlowNodes[i] === flow) {
flowDepth--;
return sharedFlowTypes[i];
}
}
}
let type: FlowType;
if (flow.flags & FlowFlags.AfterFinally) {
if (flags & FlowFlags.AfterFinally) {
// block flow edge: finally -> pre-try (for larger explanation check comment in binder.ts - bindTryStatement
(<AfterFinallyFlow>flow).locked = true;
type = getTypeAtFlowNode((<AfterFinallyFlow>flow).antecedent);
(<AfterFinallyFlow>flow).locked = false;
}
else if (flow.flags & FlowFlags.PreFinally) {
else if (flags & FlowFlags.PreFinally) {
// locked pre-finally flows are filtered out in getTypeAtFlowBranchLabel
// so here just redirect to antecedent
flow = (<PreFinallyFlow>flow).antecedent;
continue;
}
else if (flow.flags & FlowFlags.Assignment) {
else if (flags & FlowFlags.Assignment) {
type = getTypeAtFlowAssignment(<FlowAssignment>flow);
if (!type) {
flow = (<FlowAssignment>flow).antecedent;
continue;
}
}
else if (flow.flags & FlowFlags.Condition) {
else if (flags & FlowFlags.Condition) {
type = getTypeAtFlowCondition(<FlowCondition>flow);
}
else if (flow.flags & FlowFlags.SwitchClause) {
else if (flags & FlowFlags.SwitchClause) {
type = getTypeAtSwitchClause(<FlowSwitchClause>flow);
}
else if (flow.flags & FlowFlags.Label) {
else if (flags & FlowFlags.Label) {
if ((<FlowLabel>flow).antecedents.length === 1) {
flow = (<FlowLabel>flow).antecedents[0];
continue;
}
type = flow.flags & FlowFlags.BranchLabel ?
type = flags & FlowFlags.BranchLabel ?
getTypeAtFlowBranchLabel(<FlowLabel>flow) :
getTypeAtFlowLoopLabel(<FlowLabel>flow);
}
else if (flow.flags & FlowFlags.ArrayMutation) {
else if (flags & FlowFlags.ArrayMutation) {
type = getTypeAtFlowArrayMutation(<FlowArrayMutation>flow);
if (!type) {
flow = (<FlowArrayMutation>flow).antecedent;
continue;
}
}
else if (flow.flags & FlowFlags.Start) {
else if (flags & FlowFlags.Start) {
// Check if we should continue with the control flow of the containing function.
const container = (<FlowStart>flow).container;
if (container && container !== flowContainer && reference.kind !== SyntaxKind.PropertyAccessExpression && reference.kind !== SyntaxKind.ThisKeyword) {
@ -11546,12 +11581,13 @@ namespace ts {
// simply return the non-auto declared type to reduce follow-on errors.
type = convertAutoToAny(declaredType);
}
if (flow.flags & FlowFlags.Shared) {
if (flags & FlowFlags.Shared) {
// Record visited node and the associated type in the cache.
visitedFlowNodes[visitedFlowCount] = flow;
visitedFlowTypes[visitedFlowCount] = type;
visitedFlowCount++;
sharedFlowNodes[sharedFlowCount] = flow;
sharedFlowTypes[sharedFlowCount] = type;
sharedFlowCount++;
}
flowDepth--;
return type;
}
}
@ -11589,29 +11625,31 @@ namespace ts {
}
function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType {
const node = flow.node;
const expr = node.kind === SyntaxKind.CallExpression ?
(<PropertyAccessExpression>(<CallExpression>node).expression).expression :
(<ElementAccessExpression>(<BinaryExpression>node).left).expression;
if (isMatchingReference(reference, getReferenceCandidate(expr))) {
const flowType = getTypeAtFlowNode(flow.antecedent);
const type = getTypeFromFlowType(flowType);
if (getObjectFlags(type) & ObjectFlags.EvolvingArray) {
let evolvedType = <EvolvingArrayType>type;
if (node.kind === SyntaxKind.CallExpression) {
for (const arg of (<CallExpression>node).arguments) {
evolvedType = addEvolvingArrayElementType(evolvedType, arg);
if (declaredType === autoType || declaredType === autoArrayType) {
const node = flow.node;
const expr = node.kind === SyntaxKind.CallExpression ?
(<PropertyAccessExpression>(<CallExpression>node).expression).expression :
(<ElementAccessExpression>(<BinaryExpression>node).left).expression;
if (isMatchingReference(reference, getReferenceCandidate(expr))) {
const flowType = getTypeAtFlowNode(flow.antecedent);
const type = getTypeFromFlowType(flowType);
if (getObjectFlags(type) & ObjectFlags.EvolvingArray) {
let evolvedType = <EvolvingArrayType>type;
if (node.kind === SyntaxKind.CallExpression) {
for (const arg of (<CallExpression>node).arguments) {
evolvedType = addEvolvingArrayElementType(evolvedType, arg);
}
}
}
else {
const indexType = getTypeOfExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
if (isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
else {
const indexType = getTypeOfExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
if (isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
}
}
return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType));
}
return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType));
return flowType;
}
return flowType;
}
return undefined;
}
@ -16128,16 +16166,6 @@ namespace ts {
return resolveErrorCall(node);
}
// If the expression is a class of abstract type, then it cannot be instantiated.
// Note, only class declarations can be declared abstract.
// In the case of a merged class-module or class-interface declaration,
// only the class declaration node will have the Abstract flag set.
const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) {
error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(getNameOfDeclaration(valueDecl)));
return resolveErrorCall(node);
}
// TS 1.0 spec: 4.11
// If expressionType is of type Any, Args can be any argument
// list and the result of the operation is of type Any.
@ -16157,6 +16185,16 @@ namespace ts {
if (!isConstructorAccessible(node, constructSignatures[0])) {
return resolveErrorCall(node);
}
// If the expression is a class of abstract type, then it cannot be instantiated.
// Note, only class declarations can be declared abstract.
// In the case of a merged class-module or class-interface declaration,
// only the class declaration node will have the Abstract flag set.
const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) {
error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(getNameOfDeclaration(valueDecl)));
return resolveErrorCall(node);
}
return resolveCall(node, constructSignatures, candidatesOutArray);
}
@ -16665,8 +16703,9 @@ namespace ts {
}
}
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
// parameter might be a transient symbol generated by use of `arguments` in the function body.
const parameter = lastOrUndefined(signature.parameters);
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
if (isTransientSymbol(parameter) || !getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
}
@ -19935,7 +19974,14 @@ namespace ts {
if (node.kind === SyntaxKind.Block) {
checkGrammarStatementInAmbientContext(node);
}
forEach(node.statements, checkSourceElement);
if (isFunctionOrModuleBlock(node)) {
const saveFlowAnalysisDisabled = flowAnalysisDisabled;
forEach(node.statements, checkSourceElement);
flowAnalysisDisabled = saveFlowAnalysisDisabled;
}
else {
forEach(node.statements, checkSourceElement);
}
if (node.locals) {
registerForUnusedIdentifiersCheck(node);
}
@ -22525,6 +22571,7 @@ namespace ts {
deferredNodes = [];
deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
flowAnalysisDisabled = false;
forEach(node.statements, checkSourceElement);

View File

@ -1920,6 +1920,10 @@
"category": "Error",
"code": 2562
},
"The containing function or module body is too large for control flow analysis.": {
"category": "Error",
"code": 2563
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600

View File

@ -5021,6 +5021,11 @@ namespace ts {
}
}
/* @internal */
export function isFunctionOrModuleBlock(node: Node): boolean {
return isSourceFile(node) || isModuleBlock(node) || isBlock(node) && isFunctionLike(node.parent);
}
// Classes
export function isClassElement(node: Node): node is ClassElement {
const kind = node.kind;

36
src/lib/es5.d.ts vendored
View File

@ -1744,8 +1744,8 @@ interface Int8Array {
interface Int8ArrayConstructor {
readonly prototype: Int8Array;
new(length: number): Int8Array;
new(array: ArrayLike<number>): Int8Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int8Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int8Array;
/**
* The size in bytes of each element in the array.
@ -2012,8 +2012,8 @@ interface Uint8Array {
interface Uint8ArrayConstructor {
readonly prototype: Uint8Array;
new(length: number): Uint8Array;
new(array: ArrayLike<number>): Uint8Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint8Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint8Array;
/**
* The size in bytes of each element in the array.
@ -2279,8 +2279,8 @@ interface Uint8ClampedArray {
interface Uint8ClampedArrayConstructor {
readonly prototype: Uint8ClampedArray;
new(length: number): Uint8ClampedArray;
new(array: ArrayLike<number>): Uint8ClampedArray;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8ClampedArray;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint8ClampedArray;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint8ClampedArray;
/**
* The size in bytes of each element in the array.
@ -2544,8 +2544,8 @@ interface Int16Array {
interface Int16ArrayConstructor {
readonly prototype: Int16Array;
new(length: number): Int16Array;
new(array: ArrayLike<number>): Int16Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int16Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int16Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int16Array;
/**
* The size in bytes of each element in the array.
@ -2812,8 +2812,8 @@ interface Uint16Array {
interface Uint16ArrayConstructor {
readonly prototype: Uint16Array;
new(length: number): Uint16Array;
new(array: ArrayLike<number>): Uint16Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint16Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint16Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint16Array;
/**
* The size in bytes of each element in the array.
@ -3079,8 +3079,8 @@ interface Int32Array {
interface Int32ArrayConstructor {
readonly prototype: Int32Array;
new(length: number): Int32Array;
new(array: ArrayLike<number>): Int32Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int32Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int32Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int32Array;
/**
* The size in bytes of each element in the array.
@ -3345,8 +3345,8 @@ interface Uint32Array {
interface Uint32ArrayConstructor {
readonly prototype: Uint32Array;
new(length: number): Uint32Array;
new(array: ArrayLike<number>): Uint32Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint32Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint32Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint32Array;
/**
* The size in bytes of each element in the array.
@ -3612,8 +3612,8 @@ interface Float32Array {
interface Float32ArrayConstructor {
readonly prototype: Float32Array;
new(length: number): Float32Array;
new(array: ArrayLike<number>): Float32Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float32Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Float32Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Float32Array;
/**
* The size in bytes of each element in the array.
@ -3880,8 +3880,8 @@ interface Float64Array {
interface Float64ArrayConstructor {
readonly prototype: Float64Array;
new(length: number): Float64Array;
new(array: ArrayLike<number>): Float64Array;
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float64Array;
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Float64Array;
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Float64Array;
/**
* The size in bytes of each element in the array.

View File

@ -1196,16 +1196,22 @@ namespace ts.server {
if (this.projectService.globalPlugins) {
// Enable global plugins with synthetic configuration entries
for (const globalPluginName of this.projectService.globalPlugins) {
// Skip empty names from odd commandline parses
if (!globalPluginName) continue;
// Skip already-locally-loaded plugins
if (options.plugins && options.plugins.some(p => p.name === globalPluginName)) continue;
// Provide global: true so plugins can detect why they can't find their config
this.projectService.logger.info(`Loading global plugin ${globalPluginName}`);
this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths);
}
}
}
private enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]) {
this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
const log = (message: string) => {
this.projectService.logger.info(message);
};
@ -1217,7 +1223,7 @@ namespace ts.server {
return;
}
}
this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name} anywhere in paths: ${searchPaths.join(",")}`);
this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`);
}
private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) {
@ -1236,7 +1242,15 @@ namespace ts.server {
};
const pluginModule = pluginModuleFactory({ typescript: ts });
this.languageService = pluginModule.create(info);
const newLS = pluginModule.create(info);
for (const k of Object.keys(this.languageService)) {
if (!(k in newLS)) {
this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`);
(newLS as any)[k] = (this.languageService as any)[k];
}
}
this.projectService.logger.info(`Plugin validation succeded`);
this.languageService = newLS;
this.plugins.push(pluginModule);
}
catch (e) {

View File

@ -0,0 +1,14 @@
=== tests/cases/compiler/foo.js ===
// Repro for #16585
const x = {
>x : Symbol(x, Decl(foo.js, 1, 5))
bar() {
>bar : Symbol(bar, Decl(foo.js, 1, 11))
setTimeout(function() { arguments }, 0);
>setTimeout : Symbol(setTimeout, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>arguments : Symbol(arguments)
}
}

View File

@ -0,0 +1,18 @@
=== tests/cases/compiler/foo.js ===
// Repro for #16585
const x = {
>x : { [x: string]: any; bar(): void; }
>{ bar() { setTimeout(function() { arguments }, 0); }} : { [x: string]: any; bar(): void; }
bar() {
>bar : () => void
setTimeout(function() { arguments }, 0);
>setTimeout(function() { arguments }, 0) : number
>setTimeout : { (handler: (...args: any[]) => void, timeout: number): number; (handler: any, timeout?: any, ...args: any[]): number; }
>function() { arguments } : (...args: any[]) => void
>arguments : IArguments
>0 : 0
}
}

View File

@ -0,0 +1,43 @@
//// [higherOrderMappedIndexLookupInference.ts]
// @strict
function f1(a: <T>() => keyof T, b: <U>() => keyof U) {
a = b;
b = a;
}
function f2(a: <T, K extends keyof T>() => T[K], b: <U, L extends keyof U>() => U[L]) {
a = b;
b = a;
}
function f3(a: <T>() => { [K in keyof T]: T[K] }, b: <U>() => { [K in keyof U]: U[K] }) {
a = b;
b = a;
}
// Repro from #18338
type IdMapped<T> = { [K in keyof T]: T[K] }
declare const f: <T>() => IdMapped<T>;
declare const g: <U>() => { [K in keyof U]: U[K] };
const h: typeof g = f;
//// [higherOrderMappedIndexLookupInference.js]
// @strict
function f1(a, b) {
a = b;
b = a;
}
function f2(a, b) {
a = b;
b = a;
}
function f3(a, b) {
a = b;
b = a;
}
var h = f;

View File

@ -0,0 +1,98 @@
=== tests/cases/compiler/higherOrderMappedIndexLookupInference.ts ===
// @strict
function f1(a: <T>() => keyof T, b: <U>() => keyof U) {
>f1 : Symbol(f1, Decl(higherOrderMappedIndexLookupInference.ts, 0, 0))
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 2, 12))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 2, 16))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 2, 16))
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 2, 32))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 2, 37))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 2, 37))
a = b;
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 2, 12))
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 2, 32))
b = a;
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 2, 32))
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 2, 12))
}
function f2(a: <T, K extends keyof T>() => T[K], b: <U, L extends keyof U>() => U[L]) {
>f2 : Symbol(f2, Decl(higherOrderMappedIndexLookupInference.ts, 5, 1))
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 7, 12))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 7, 16))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 7, 18))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 7, 16))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 7, 16))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 7, 18))
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 7, 48))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 7, 53))
>L : Symbol(L, Decl(higherOrderMappedIndexLookupInference.ts, 7, 55))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 7, 53))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 7, 53))
>L : Symbol(L, Decl(higherOrderMappedIndexLookupInference.ts, 7, 55))
a = b;
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 7, 12))
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 7, 48))
b = a;
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 7, 48))
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 7, 12))
}
function f3(a: <T>() => { [K in keyof T]: T[K] }, b: <U>() => { [K in keyof U]: U[K] }) {
>f3 : Symbol(f3, Decl(higherOrderMappedIndexLookupInference.ts, 10, 1))
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 12, 12))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 12, 16))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 12, 27))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 12, 16))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 12, 16))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 12, 27))
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 12, 49))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 12, 54))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 12, 65))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 12, 54))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 12, 54))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 12, 65))
a = b;
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 12, 12))
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 12, 49))
b = a;
>b : Symbol(b, Decl(higherOrderMappedIndexLookupInference.ts, 12, 49))
>a : Symbol(a, Decl(higherOrderMappedIndexLookupInference.ts, 12, 12))
}
// Repro from #18338
type IdMapped<T> = { [K in keyof T]: T[K] }
>IdMapped : Symbol(IdMapped, Decl(higherOrderMappedIndexLookupInference.ts, 15, 1))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 19, 14))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 19, 22))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 19, 14))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 19, 14))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 19, 22))
declare const f: <T>() => IdMapped<T>;
>f : Symbol(f, Decl(higherOrderMappedIndexLookupInference.ts, 21, 13))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 21, 18))
>IdMapped : Symbol(IdMapped, Decl(higherOrderMappedIndexLookupInference.ts, 15, 1))
>T : Symbol(T, Decl(higherOrderMappedIndexLookupInference.ts, 21, 18))
declare const g: <U>() => { [K in keyof U]: U[K] };
>g : Symbol(g, Decl(higherOrderMappedIndexLookupInference.ts, 22, 13))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 22, 18))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 22, 29))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 22, 18))
>U : Symbol(U, Decl(higherOrderMappedIndexLookupInference.ts, 22, 18))
>K : Symbol(K, Decl(higherOrderMappedIndexLookupInference.ts, 22, 29))
const h: typeof g = f;
>h : Symbol(h, Decl(higherOrderMappedIndexLookupInference.ts, 24, 5))
>g : Symbol(g, Decl(higherOrderMappedIndexLookupInference.ts, 22, 13))
>f : Symbol(f, Decl(higherOrderMappedIndexLookupInference.ts, 21, 13))

View File

@ -0,0 +1,104 @@
=== tests/cases/compiler/higherOrderMappedIndexLookupInference.ts ===
// @strict
function f1(a: <T>() => keyof T, b: <U>() => keyof U) {
>f1 : (a: <T>() => keyof T, b: <U>() => keyof U) => void
>a : <T>() => keyof T
>T : T
>T : T
>b : <U>() => keyof U
>U : U
>U : U
a = b;
>a = b : <U>() => keyof U
>a : <T>() => keyof T
>b : <U>() => keyof U
b = a;
>b = a : <T>() => keyof T
>b : <U>() => keyof U
>a : <T>() => keyof T
}
function f2(a: <T, K extends keyof T>() => T[K], b: <U, L extends keyof U>() => U[L]) {
>f2 : (a: <T, K extends keyof T>() => T[K], b: <U, L extends keyof U>() => U[L]) => void
>a : <T, K extends keyof T>() => T[K]
>T : T
>K : K
>T : T
>T : T
>K : K
>b : <U, L extends keyof U>() => U[L]
>U : U
>L : L
>U : U
>U : U
>L : L
a = b;
>a = b : <U, L extends keyof U>() => U[L]
>a : <T, K extends keyof T>() => T[K]
>b : <U, L extends keyof U>() => U[L]
b = a;
>b = a : <T, K extends keyof T>() => T[K]
>b : <U, L extends keyof U>() => U[L]
>a : <T, K extends keyof T>() => T[K]
}
function f3(a: <T>() => { [K in keyof T]: T[K] }, b: <U>() => { [K in keyof U]: U[K] }) {
>f3 : (a: <T>() => { [K in keyof T]: T[K]; }, b: <U>() => { [K in keyof U]: U[K]; }) => void
>a : <T>() => { [K in keyof T]: T[K]; }
>T : T
>K : K
>T : T
>T : T
>K : K
>b : <U>() => { [K in keyof U]: U[K]; }
>U : U
>K : K
>U : U
>U : U
>K : K
a = b;
>a = b : <U>() => { [K in keyof U]: U[K]; }
>a : <T>() => { [K in keyof T]: T[K]; }
>b : <U>() => { [K in keyof U]: U[K]; }
b = a;
>b = a : <T>() => { [K in keyof T]: T[K]; }
>b : <U>() => { [K in keyof U]: U[K]; }
>a : <T>() => { [K in keyof T]: T[K]; }
}
// Repro from #18338
type IdMapped<T> = { [K in keyof T]: T[K] }
>IdMapped : IdMapped<T>
>T : T
>K : K
>T : T
>T : T
>K : K
declare const f: <T>() => IdMapped<T>;
>f : <T>() => IdMapped<T>
>T : T
>IdMapped : IdMapped<T>
>T : T
declare const g: <U>() => { [K in keyof U]: U[K] };
>g : <U>() => { [K in keyof U]: U[K]; }
>U : U
>K : K
>U : U
>U : U
>K : K
const h: typeof g = f;
>h : <U>() => { [K in keyof U]: U[K]; }
>g : <U>() => { [K in keyof U]: U[K]; }
>f : <T>() => IdMapped<T>

View File

@ -0,0 +1,23 @@
//// [intersectionTypeInference2.ts]
declare function f<T>(x: { prop: T }): T;
declare const a: { prop: string } & { prop: number };
declare const b: { prop: string & number };
f(a); // string & number
f(b); // string & number
// Repro from #18354
declare function f2<T, Key extends keyof T>(obj: {[K in keyof T]: T[K]}, key: Key): T[Key];
declare const obj: { a: string } & { b: string };
f2(obj, 'a');
f2(obj, 'b');
//// [intersectionTypeInference2.js]
f(a); // string & number
f(b); // string & number
f2(obj, 'a');
f2(obj, 'b');

View File

@ -0,0 +1,56 @@
=== tests/cases/conformance/types/intersection/intersectionTypeInference2.ts ===
declare function f<T>(x: { prop: T }): T;
>f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 0, 19))
>x : Symbol(x, Decl(intersectionTypeInference2.ts, 0, 22))
>prop : Symbol(prop, Decl(intersectionTypeInference2.ts, 0, 26))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 0, 19))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 0, 19))
declare const a: { prop: string } & { prop: number };
>a : Symbol(a, Decl(intersectionTypeInference2.ts, 2, 13))
>prop : Symbol(prop, Decl(intersectionTypeInference2.ts, 2, 18))
>prop : Symbol(prop, Decl(intersectionTypeInference2.ts, 2, 37))
declare const b: { prop: string & number };
>b : Symbol(b, Decl(intersectionTypeInference2.ts, 3, 13))
>prop : Symbol(prop, Decl(intersectionTypeInference2.ts, 3, 18))
f(a); // string & number
>f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0))
>a : Symbol(a, Decl(intersectionTypeInference2.ts, 2, 13))
f(b); // string & number
>f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0))
>b : Symbol(b, Decl(intersectionTypeInference2.ts, 3, 13))
// Repro from #18354
declare function f2<T, Key extends keyof T>(obj: {[K in keyof T]: T[K]}, key: Key): T[Key];
>f2 : Symbol(f2, Decl(intersectionTypeInference2.ts, 6, 5))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 10, 20))
>Key : Symbol(Key, Decl(intersectionTypeInference2.ts, 10, 22))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 10, 20))
>obj : Symbol(obj, Decl(intersectionTypeInference2.ts, 10, 44))
>K : Symbol(K, Decl(intersectionTypeInference2.ts, 10, 51))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 10, 20))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 10, 20))
>K : Symbol(K, Decl(intersectionTypeInference2.ts, 10, 51))
>key : Symbol(key, Decl(intersectionTypeInference2.ts, 10, 72))
>Key : Symbol(Key, Decl(intersectionTypeInference2.ts, 10, 22))
>T : Symbol(T, Decl(intersectionTypeInference2.ts, 10, 20))
>Key : Symbol(Key, Decl(intersectionTypeInference2.ts, 10, 22))
declare const obj: { a: string } & { b: string };
>obj : Symbol(obj, Decl(intersectionTypeInference2.ts, 12, 13))
>a : Symbol(a, Decl(intersectionTypeInference2.ts, 12, 20))
>b : Symbol(b, Decl(intersectionTypeInference2.ts, 12, 36))
f2(obj, 'a');
>f2 : Symbol(f2, Decl(intersectionTypeInference2.ts, 6, 5))
>obj : Symbol(obj, Decl(intersectionTypeInference2.ts, 12, 13))
f2(obj, 'b');
>f2 : Symbol(f2, Decl(intersectionTypeInference2.ts, 6, 5))
>obj : Symbol(obj, Decl(intersectionTypeInference2.ts, 12, 13))

View File

@ -0,0 +1,62 @@
=== tests/cases/conformance/types/intersection/intersectionTypeInference2.ts ===
declare function f<T>(x: { prop: T }): T;
>f : <T>(x: { prop: T; }) => T
>T : T
>x : { prop: T; }
>prop : T
>T : T
>T : T
declare const a: { prop: string } & { prop: number };
>a : { prop: string; } & { prop: number; }
>prop : string
>prop : number
declare const b: { prop: string & number };
>b : { prop: string & number; }
>prop : string & number
f(a); // string & number
>f(a) : string & number
>f : <T>(x: { prop: T; }) => T
>a : { prop: string; } & { prop: number; }
f(b); // string & number
>f(b) : string & number
>f : <T>(x: { prop: T; }) => T
>b : { prop: string & number; }
// Repro from #18354
declare function f2<T, Key extends keyof T>(obj: {[K in keyof T]: T[K]}, key: Key): T[Key];
>f2 : <T, Key extends keyof T>(obj: { [K in keyof T]: T[K]; }, key: Key) => T[Key]
>T : T
>Key : Key
>T : T
>obj : { [K in keyof T]: T[K]; }
>K : K
>T : T
>T : T
>K : K
>key : Key
>Key : Key
>T : T
>Key : Key
declare const obj: { a: string } & { b: string };
>obj : { a: string; } & { b: string; }
>a : string
>b : string
f2(obj, 'a');
>f2(obj, 'a') : string
>f2 : <T, Key extends keyof T>(obj: { [K in keyof T]: T[K]; }, key: Key) => T[Key]
>obj : { a: string; } & { b: string; }
>'a' : "a"
f2(obj, 'b');
>f2(obj, 'b') : string
>f2 : <T, Key extends keyof T>(obj: { [K in keyof T]: T[K]; }, key: Key) => T[Key]
>obj : { a: string; } & { b: string; }
>'b' : "b"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
tests/cases/compiler/newAbstractInstance.ts(3,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
==== tests/cases/compiler/newAbstractInstance.ts (1 errors) ====
abstract class B { }
declare const b: B;
new b();
~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.

View File

@ -0,0 +1,13 @@
//// [newAbstractInstance.ts]
abstract class B { }
declare const b: B;
new b();
//// [newAbstractInstance.js]
var B = /** @class */ (function () {
function B() {
}
return B;
}());
new b();

View File

@ -0,0 +1,11 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @lib: es2017, dom
// @Filename: foo.js
// Repro for #16585
const x = {
bar() {
setTimeout(function() { arguments }, 0);
}
}

View File

@ -0,0 +1,25 @@
// @strict
function f1(a: <T>() => keyof T, b: <U>() => keyof U) {
a = b;
b = a;
}
function f2(a: <T, K extends keyof T>() => T[K], b: <U, L extends keyof U>() => U[L]) {
a = b;
b = a;
}
function f3(a: <T>() => { [K in keyof T]: T[K] }, b: <U>() => { [K in keyof U]: U[K] }) {
a = b;
b = a;
}
// Repro from #18338
type IdMapped<T> = { [K in keyof T]: T[K] }
declare const f: <T>() => IdMapped<T>;
declare const g: <U>() => { [K in keyof U]: U[K] };
const h: typeof g = f;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
abstract class B { }
declare const b: B;
new b();

View File

@ -0,0 +1,15 @@
declare function f<T>(x: { prop: T }): T;
declare const a: { prop: string } & { prop: number };
declare const b: { prop: string & number };
f(a); // string & number
f(b); // string & number
// Repro from #18354
declare function f2<T, Key extends keyof T>(obj: {[K in keyof T]: T[K]}, key: Key): T[Key];
declare const obj: { a: string } & { b: string };
f2(obj, 'a');
f2(obj, 'b');

View File

@ -15,5 +15,5 @@
verify.quickInfos({
1: "function ComponentSpecific<number>(l: {\n prop: number;\n}): any",
2: "function ComponentSpecific<number>(l: {\n prop: number;\n}): any"
2: "function ComponentSpecific<number & \"hello\">(l: {\n prop: number & \"hello\";\n}): any"
});

View File

@ -24,6 +24,6 @@ verify.quickInfos({
3: "function OverloadComponent<boolean, string>(attr: {\n b: string;\n a: boolean;\n}): any (+2 overloads)",
4: "function OverloadComponent<number>(attr: {\n b: number;\n a?: string;\n \"ignore-prop\": boolean;\n}): any (+2 overloads)",
5: "function OverloadComponent(): any (+2 overloads)",
6: "function OverloadComponent<boolean, string>(attr: {\n b: string;\n a: boolean;\n}): any (+2 overloads)",
7: "function OverloadComponent<boolean, number>(attr: {\n b: number;\n a: boolean;\n}): any (+2 overloads)",
6: "function OverloadComponent<boolean, string & number>(attr: {\n b: string & number;\n a: boolean;\n}): any (+2 overloads)",
7: "function OverloadComponent<boolean, number & string>(attr: {\n b: number & string;\n a: boolean;\n}): any (+2 overloads)",
});