diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff105ce9d1cb2..92abee8b9d113 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -66,6 +66,7 @@ namespace ts { const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters; const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System; const strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks; + const strictFunctionTypes = compilerOptions.strictFunctionTypes === undefined ? compilerOptions.strict : compilerOptions.strictFunctionTypes; const noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny; const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; @@ -281,6 +282,11 @@ namespace ts { const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const markerSuperType = createType(TypeFlags.TypeParameter); + const markerSubType = createType(TypeFlags.TypeParameter); + markerSubType.constraint = markerSuperType; + const markerOtherType = createType(TypeFlags.TypeParameter); + const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); @@ -2508,7 +2514,7 @@ namespace ts { return typeReferenceToTypeNode(type); } if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { - const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false); + const name = type.symbol ? symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false) : createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } @@ -6716,7 +6722,7 @@ namespace ts { } function getConstraintDeclaration(type: TypeParameter) { - return getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter).constraint; + return type.symbol && getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter).constraint; } function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type { @@ -8528,6 +8534,9 @@ namespace ts { source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } + const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown; + const strictVariance = strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration && + kind !== SyntaxKind.MethodSignature && kind !== SyntaxKind.Constructor; let result = Ternary.True; const sourceThisType = getThisTypeOfSignature(source); @@ -8535,7 +8544,7 @@ namespace ts { const targetThisType = getThisTypeOfSignature(target); if (targetThisType) { // void sources are assignable to anything. - const related = compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false) + const related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false) || compareTypes(targetThisType, sourceThisType, reportErrors); if (!related) { if (reportErrors) { @@ -8569,7 +8578,7 @@ namespace ts { (getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable); const related = callbacks ? compareSignaturesRelated(targetSig, sourceSig, /*checkAsCallback*/ true, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) : - !checkAsCallback && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); + !checkAsCallback && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); if (!related) { if (reportErrors) { errorReporter(Diagnostics.Types_of_parameters_0_and_1_are_incompatible, @@ -9181,7 +9190,7 @@ namespace ts { return result; } - function typeArgumentsRelatedTo(source: TypeReference, target: TypeReference, reportErrors: boolean): Ternary { + function typeArgumentsRelatedTo(source: TypeReference, target: TypeReference, variances: Variance[], reportErrors: boolean): Ternary { const sources = source.typeArguments || emptyArray; const targets = target.typeArguments || emptyArray; if (sources.length !== targets.length && relation === identityRelation) { @@ -9190,11 +9199,45 @@ namespace ts { const length = sources.length <= targets.length ? sources.length : targets.length; let result = Ternary.True; for (let i = 0; i < length; i++) { - const related = isRelatedTo(sources[i], targets[i], reportErrors); - if (!related) { - return Ternary.False; + // When variance information isn't available we default to covariance. This happens + // in the process of computing variance information for recursive types and when + // comparing 'this' type arguments. + const variance = i < variances.length ? variances[i] : Variance.Covariant; + // We ignore arguments for independent type parameters (because they're never witnessed). + if (variance !== Variance.Independent) { + const s = sources[i]; + const t = targets[i]; + let related = Ternary.True; + if (variance === Variance.Covariant) { + related = isRelatedTo(s, t, reportErrors); + } + else if (variance === Variance.Contravariant) { + related = isRelatedTo(t, s, reportErrors); + } + else if (variance === Variance.Bivariant) { + // In the bivariant case we first compare contravariantly without reporting + // errors. Then, if that doesn't succeed, we compare covariantly with error + // reporting. Thus, error elaboration will be based on the the covariant check, + // which is generally easier to reason about. + related = isRelatedTo(t, s, /*reportErrors*/ false); + if (!related) { + related = isRelatedTo(s, t, reportErrors); + } + } + else { + // In the invariant case we first compare covariantly, and only when that + // succeeds do we proceed to compare contravariantly. Thus, error elaboration + // will typically be based on the covariant check. + related = isRelatedTo(s, t, reportErrors); + if (related) { + related &= isRelatedTo(t, s, reportErrors); + } + } + if (!related) { + return Ternary.False; + } + result &= related; } - result &= related; } return result; } @@ -9327,8 +9370,6 @@ namespace ts { if (!constraint || constraint.flags & TypeFlags.Any) { constraint = emptyObjectType; } - // The constraint may need to be further instantiated with its 'this' type. - constraint = getTypeWithThisArgument(constraint, source); // Report constraint errors only if the constraint is not the empty object type const reportConstraintErrors = reportErrors && constraint !== emptyObjectType; if (result = isRelatedTo(constraint, target, reportConstraintErrors)) { @@ -9357,11 +9398,34 @@ namespace ts { } } else { - if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source).target === (target).target) { - // We have type references to same target type, see if relationship holds for all type arguments - if (result = typeArgumentsRelatedTo(source, target, reportErrors)) { + if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source).target === (target).target && + !(source.flags & TypeFlags.MarkerType || target.flags & TypeFlags.MarkerType)) { + // We have type references to the same generic type, and the type references are not marker + // type references (which are intended by be compared structurally). Obtain the variance + // information for the type parameters and relate the type arguments accordingly. + const variances = getVariances((source).target); + if (result = typeArgumentsRelatedTo(source, target, variances, reportErrors)) { return result; } + // The type arguments did not relate appropriately, but it may be because we have no variance + // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type + // arguments). It might also be the case that the target type has a 'void' type argument for + // a covariant type parameter that is only used in return positions within the generic type + // (in which case any type argument is permitted on the source side). In those cases we proceed + // with a structural comparison. Otherwise, we know for certain the instantiations aren't + // related and we can return here. + if (variances !== emptyArray && !hasCovariantVoidArgument(target, variances)) { + // In some cases generic types that are covariant in regular type checking mode become + // invariant in --strictFunctionTypes mode because one or more type parameters are used in + // both co- and contravariant positions. In order to make it easier to diagnose *why* such + // types are invariant, if any of the type parameters are invariant we reset the reported + // errors and instead force a structural comparison (which will include elaborations that + // reveal the reason). + if (!(reportErrors && some(variances, v => v === Variance.Invariant))) { + return Ternary.False; + } + errorInfo = saveErrorInfo; + } } // Even if relationship doesn't hold for unions, intersections, or generic type references, // it may hold in a structural comparison. @@ -9772,6 +9836,69 @@ namespace ts { } } + // Return a type reference where the source type parameter is replaced with the target marker + // type, and flag the result as a marker type reference. + function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) { + const result = createTypeReference(type, map(type.typeParameters, t => t === source ? target : t)); + result.flags |= TypeFlags.MarkerType; + return result; + } + + // Return an array containing the variance of each type parameter. The variance is effectively + // a digest of the type comparisons that occur for each type argument when instantiations of the + // generic type are structurally compared. We infer the variance information by comparing + // instantiations of the generic type for type arguments with known relations. The function + // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function + // has been invoked recursively for the given generic type. + function getVariances(type: GenericType): Variance[] { + if (!strictFunctionTypes) { + return emptyArray; + } + const typeParameters = type.typeParameters || emptyArray; + let variances = type.variances; + if (!variances) { + if (type === globalArrayType || type === globalReadonlyArrayType) { + // Arrays are known to be covariant, no need to spend time computing this + variances = [Variance.Covariant]; + } + else { + // The emptyArray singleton is used to signal a recursive invocation. + type.variances = emptyArray; + variances = []; + for (const tp of typeParameters) { + // We first compare instantiations where the type parameter is replaced with + // marker types that have a known subtype relationship. From this we can infer + // invariance, covariance, contravariance or bivariance. + const typeWithSuper = getMarkerTypeReference(type, tp, markerSuperType); + const typeWithSub = getMarkerTypeReference(type, tp, markerSubType); + let variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? Variance.Covariant : 0) | + (isTypeAssignableTo(typeWithSuper, typeWithSub) ? Variance.Contravariant : 0); + // If the instantiations appear to be related bivariantly it may be because the + // type parameter is independent (i.e. it isn't witnessed anywhere in the generic + // type). To determine this we compare instantiations where the type parameter is + // replaced with marker types that are known to be unrelated. + if (variance === Variance.Bivariant && isTypeAssignableTo(getMarkerTypeReference(type, tp, markerOtherType), typeWithSuper)) { + variance = Variance.Independent; + } + variances.push(variance); + } + } + type.variances = variances; + } + return variances; + } + + // Return true if the given type reference has a 'void' type argument for a covariant type parameter. + // See comment at call in recursiveTypeRelatedTo for when this case matters. + function hasCovariantVoidArgument(type: TypeReference, variances: Variance[]): boolean { + for (let i = 0; i < variances.length; i++) { + if (variances[i] === Variance.Covariant && type.typeArguments[i].flags & TypeFlags.Void) { + return true; + } + } + return false; + } + function isUnconstrainedTypeParameter(type: Type) { return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter(type); } @@ -10047,6 +10174,11 @@ namespace ts { getUnionType(types, /*subtypeReduction*/ true); } + // Return the leftmost type for which no type to the right is a subtype. + function getCommonSubtype(types: Type[]) { + return reduceLeft(types, (s, t) => isTypeSubtypeOf(t, s) ? t : s); + } + function isArrayType(type: Type): boolean { return getObjectFlags(type) & ObjectFlags.Reference && (type).target === globalArrayType; } @@ -10573,8 +10705,14 @@ namespace ts { const sourceTypes = (source).typeArguments || emptyArray; const targetTypes = (target).typeArguments || emptyArray; const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length; + const variances = getVariances((source).target); for (let i = 0; i < count; i++) { - inferFromTypes(sourceTypes[i], targetTypes[i]); + if (i < variances.length && variances[i] === Variance.Contravariant) { + inferFromContravariantTypes(sourceTypes[i], targetTypes[i]); + } + else { + inferFromTypes(sourceTypes[i], targetTypes[i]); + } } } else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) { @@ -10645,6 +10783,17 @@ namespace ts { } } + function inferFromContravariantTypes(source: Type, target: Type) { + if (strictFunctionTypes) { + priority ^= InferencePriority.Contravariant; + inferFromTypes(source, target); + priority ^= InferencePriority.Contravariant; + } + else { + inferFromTypes(source, target); + } + } + function getInferenceInfoForType(type: Type) { if (type.flags & TypeFlags.TypeVariable) { for (const inference of inferences) { @@ -10722,7 +10871,7 @@ namespace ts { } function inferFromSignature(source: Signature, target: Signature) { - forEachMatchingParameterType(source, target, inferFromTypes); + forEachMatchingParameterType(source, target, inferFromContravariantTypes); if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) { inferFromTypes(source.typePredicate.type, target.typePredicate.type); @@ -10795,11 +10944,13 @@ namespace ts { !hasPrimitiveConstraint(inference.typeParameter) && (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); const baseCandidates = widenLiteralTypes ? sameMap(inference.candidates, getWidenedLiteralType) : inference.candidates; - // Infer widened union or supertype, or the unknown type for no common supertype. We infer union types - // for inferences coming from return types in order to avoid common supertype failures. - const unionOrSuperType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? - getUnionType(baseCandidates, /*subtypeReduction*/ true) : getCommonSupertype(baseCandidates); - inferredType = getWidenedType(unionOrSuperType); + // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if + // union types were requested or if all inferences were made from the return type position, infer a + // union type. Otherwise, infer a common supertype. + const unwidenedType = inference.priority & InferencePriority.Contravariant ? getCommonSubtype(baseCandidates) : + context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, /*subtypeReduction*/ true) : + getCommonSupertype(baseCandidates); + inferredType = getWidenedType(unwidenedType); } else if (context.flags & InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. @@ -18849,7 +19000,7 @@ namespace ts { const typeArgument = typeArguments[i]; result = result && checkTypeAssignableTo( typeArgument, - getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), + instantiateType(constraint, mapper), typeArgumentNodes[i], Diagnostics.Type_0_does_not_satisfy_the_constraint_1); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 54e5ee1d01dbc..b63442bc89a5a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -269,6 +269,13 @@ namespace ts { category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Enable_strict_null_checks }, + { + name: "strictFunctionTypes", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Strict_Type_Checking_Options, + description: Diagnostics.Enable_strict_checking_of_function_types + }, { name: "noImplicitThis", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4465976d170c0..854d09761cd4a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3314,6 +3314,10 @@ "category": "Message", "code": 6185 }, + "Enable strict checking of function types.": { + "category": "Message", + "code": 6186 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1f27edcaf89d9..010368629809d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3215,6 +3215,7 @@ namespace ts { NonPrimitive = 1 << 24, // intrinsic object type /* @internal */ JsxAttributes = 1 << 25, // Jsx attributes type + MarkerType = 1 << 26, // Marker type used for variance probing /* @internal */ Nullable = Undefined | Null, @@ -3343,10 +3344,21 @@ namespace ts { typeArguments?: Type[]; // Type reference type arguments (undefined if none) } + /* @internal */ + export const enum Variance { + Invariant = 0, // Neither covariant nor contravariant + Covariant = 1, // Covariant + Contravariant = 2, // Contravariant + Bivariant = 3, // Both covariant and contravariant + Independent = 4, // Unwitnessed type parameter + } + // Generic class and interface types export interface GenericType extends InterfaceType, TypeReference { /* @internal */ - instantiations: Map; // Generic instantiation cache + instantiations: Map; // Generic instantiation cache + /* @internal */ + variances?: Variance[]; // Variance of each type parameter } export interface UnionOrIntersectionType extends Type { @@ -3522,9 +3534,10 @@ namespace ts { } export const enum InferencePriority { - NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type - MappedType = 1 << 1, // Reverse inference for mapped type - ReturnType = 1 << 2, // Inference made from return type of generic function + Contravariant = 1 << 0, // Inference from contravariant position + NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type + MappedType = 1 << 2, // Reverse inference for mapped type + ReturnType = 1 << 3, // Inference made from return type of generic function } export interface InferenceInfo { @@ -3707,6 +3720,7 @@ namespace ts { sourceMap?: boolean; sourceRoot?: string; strict?: boolean; + strictFunctionTypes?: boolean; // Always combine with strict property strictNullChecks?: boolean; // Always combine with strict property /* @internal */ stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index d4ee81e497424..420be2f0f5dc4 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -4233,11 +4233,7 @@ interface HTMLBodyElement extends HTMLElement { onafterprint: (this: HTMLBodyElement, ev: Event) => any; onbeforeprint: (this: HTMLBodyElement, ev: Event) => any; onbeforeunload: (this: HTMLBodyElement, ev: BeforeUnloadEvent) => any; - onblur: (this: HTMLBodyElement, ev: FocusEvent) => any; - onerror: (this: HTMLBodyElement, ev: ErrorEvent) => any; - onfocus: (this: HTMLBodyElement, ev: FocusEvent) => any; onhashchange: (this: HTMLBodyElement, ev: HashChangeEvent) => any; - onload: (this: HTMLBodyElement, ev: Event) => any; onmessage: (this: HTMLBodyElement, ev: MessageEvent) => any; onoffline: (this: HTMLBodyElement, ev: Event) => any; ononline: (this: HTMLBodyElement, ev: Event) => any; @@ -4246,7 +4242,6 @@ interface HTMLBodyElement extends HTMLElement { onpageshow: (this: HTMLBodyElement, ev: PageTransitionEvent) => any; onpopstate: (this: HTMLBodyElement, ev: PopStateEvent) => any; onresize: (this: HTMLBodyElement, ev: UIEvent) => any; - onscroll: (this: HTMLBodyElement, ev: UIEvent) => any; onstorage: (this: HTMLBodyElement, ev: StorageEvent) => any; onunload: (this: HTMLBodyElement, ev: Event) => any; text: any; @@ -4901,10 +4896,6 @@ interface HTMLFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves whether the user can resize the frame. */ noResize: boolean; - /** - * Raised when the object has been completely received from the server. - */ - onload: (this: HTMLFrameElement, ev: Event) => any; /** * Sets or retrieves whether the frame can be scrolled. */ @@ -4970,17 +4961,10 @@ interface HTMLFrameSetElement extends HTMLElement { onafterprint: (this: HTMLFrameSetElement, ev: Event) => any; onbeforeprint: (this: HTMLFrameSetElement, ev: Event) => any; onbeforeunload: (this: HTMLFrameSetElement, ev: BeforeUnloadEvent) => any; - /** - * Fires when the object loses the input focus. - */ - onblur: (this: HTMLFrameSetElement, ev: FocusEvent) => any; - onerror: (this: HTMLFrameSetElement, ev: ErrorEvent) => any; /** * Fires when the object receives focus. */ - onfocus: (this: HTMLFrameSetElement, ev: FocusEvent) => any; onhashchange: (this: HTMLFrameSetElement, ev: HashChangeEvent) => any; - onload: (this: HTMLFrameSetElement, ev: Event) => any; onmessage: (this: HTMLFrameSetElement, ev: MessageEvent) => any; onoffline: (this: HTMLFrameSetElement, ev: Event) => any; ononline: (this: HTMLFrameSetElement, ev: Event) => any; @@ -4989,7 +4973,6 @@ interface HTMLFrameSetElement extends HTMLElement { onpageshow: (this: HTMLFrameSetElement, ev: PageTransitionEvent) => any; onpopstate: (this: HTMLFrameSetElement, ev: PopStateEvent) => any; onresize: (this: HTMLFrameSetElement, ev: UIEvent) => any; - onscroll: (this: HTMLFrameSetElement, ev: UIEvent) => any; onstorage: (this: HTMLFrameSetElement, ev: StorageEvent) => any; onunload: (this: HTMLFrameSetElement, ev: Event) => any; /** @@ -5125,10 +5108,7 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves whether the user can resize the frame. */ noResize: boolean; - /** - * Raised when the object has been completely received from the server. - */ - onload: (this: HTMLIFrameElement, ev: Event) => any; + readonly sandbox: DOMSettableTokenList; /** * Sets or retrieves whether the frame can be scrolled. diff --git a/tests/baselines/reference/fuzzy.errors.txt b/tests/baselines/reference/fuzzy.errors.txt index c3f05fd7f2f04..b32f225a33e31 100644 --- a/tests/baselines/reference/fuzzy.errors.txt +++ b/tests/baselines/reference/fuzzy.errors.txt @@ -4,6 +4,7 @@ tests/cases/compiler/fuzzy.ts(21,13): error TS2322: Type '{ anything: number; on Types of property 'oneI' are incompatible. Type 'this' is not assignable to type 'I'. Type 'C' is not assignable to type 'I'. + Property 'alsoWorks' is missing in type 'C'. tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' cannot be converted to type 'R'. Property 'anything' is missing in type '{ oneI: this; }'. @@ -38,6 +39,7 @@ tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' canno !!! error TS2322: Types of property 'oneI' are incompatible. !!! error TS2322: Type 'this' is not assignable to type 'I'. !!! error TS2322: Type 'C' is not assignable to type 'I'. +!!! error TS2322: Property 'alsoWorks' is missing in type 'C'. } worksToo():R { diff --git a/tests/baselines/reference/strictFunctionTypes1.js b/tests/baselines/reference/strictFunctionTypes1.js new file mode 100644 index 0000000000000..e802c4435616d --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypes1.js @@ -0,0 +1,42 @@ +//// [strictFunctionTypes1.ts] +declare function f1(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void; +declare function f2(obj: T, f1: (x: T) => void, f2: (x: T) => void): T; +declare function f3(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T; + +interface Func { (x: T): void } + +declare function f4(f1: Func, f2: Func): Func; + +declare function fo(x: Object): void; +declare function fs(x: string): void; +declare function fx(f: (x: "def") => void): void; + +const x1 = f1(fo, fs); // (x: string) => void +const x2 = f2("abc", fo, fs); // "abc" +const x3 = f3("abc", fo, fx); // "abc" | "def" +const x4 = f4(fo, fs); // Func + + +//// [strictFunctionTypes1.js] +"use strict"; +var x1 = f1(fo, fs); // (x: string) => void +var x2 = f2("abc", fo, fs); // "abc" +var x3 = f3("abc", fo, fx); // "abc" | "def" +var x4 = f4(fo, fs); // Func + + +//// [strictFunctionTypes1.d.ts] +declare function f1(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void; +declare function f2(obj: T, f1: (x: T) => void, f2: (x: T) => void): T; +declare function f3(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T; +interface Func { + (x: T): void; +} +declare function f4(f1: Func, f2: Func): Func; +declare function fo(x: Object): void; +declare function fs(x: string): void; +declare function fx(f: (x: "def") => void): void; +declare const x1: (x: string) => void; +declare const x2 = "abc"; +declare const x3: string; +declare const x4: Func; diff --git a/tests/baselines/reference/strictFunctionTypes1.symbols b/tests/baselines/reference/strictFunctionTypes1.symbols new file mode 100644 index 0000000000000..70253411201db --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypes1.symbols @@ -0,0 +1,96 @@ +=== tests/cases/compiler/strictFunctionTypes1.ts === +declare function f1(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void; +>f1 : Symbol(f1, Decl(strictFunctionTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 0, 20)) +>f1 : Symbol(f1, Decl(strictFunctionTypes1.ts, 0, 23)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 0, 28)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 0, 20)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 0, 42)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 0, 48)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 0, 20)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 0, 65)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 0, 20)) + +declare function f2(obj: T, f1: (x: T) => void, f2: (x: T) => void): T; +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 0, 79)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 1, 20)) +>obj : Symbol(obj, Decl(strictFunctionTypes1.ts, 1, 23)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 1, 20)) +>f1 : Symbol(f1, Decl(strictFunctionTypes1.ts, 1, 30)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 1, 36)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 1, 20)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 1, 50)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 1, 56)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 1, 20)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 1, 20)) + +declare function f3(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T; +>f3 : Symbol(f3, Decl(strictFunctionTypes1.ts, 1, 74)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 2, 20)) +>obj : Symbol(obj, Decl(strictFunctionTypes1.ts, 2, 23)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 2, 20)) +>f1 : Symbol(f1, Decl(strictFunctionTypes1.ts, 2, 30)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 2, 36)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 2, 20)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 2, 50)) +>f : Symbol(f, Decl(strictFunctionTypes1.ts, 2, 56)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 2, 60)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 2, 20)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 2, 20)) + +interface Func { (x: T): void } +>Func : Symbol(Func, Decl(strictFunctionTypes1.ts, 2, 87)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 4, 15)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 4, 21)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 4, 15)) + +declare function f4(f1: Func, f2: Func): Func; +>f4 : Symbol(f4, Decl(strictFunctionTypes1.ts, 4, 34)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 6, 20)) +>f1 : Symbol(f1, Decl(strictFunctionTypes1.ts, 6, 23)) +>Func : Symbol(Func, Decl(strictFunctionTypes1.ts, 2, 87)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 6, 20)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 6, 35)) +>Func : Symbol(Func, Decl(strictFunctionTypes1.ts, 2, 87)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 6, 20)) +>Func : Symbol(Func, Decl(strictFunctionTypes1.ts, 2, 87)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 6, 20)) + +declare function fo(x: Object): void; +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 8, 20)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare function fs(x: string): void; +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 9, 20)) + +declare function fx(f: (x: "def") => void): void; +>fx : Symbol(fx, Decl(strictFunctionTypes1.ts, 9, 37)) +>f : Symbol(f, Decl(strictFunctionTypes1.ts, 10, 20)) +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 10, 24)) + +const x1 = f1(fo, fs); // (x: string) => void +>x1 : Symbol(x1, Decl(strictFunctionTypes1.ts, 12, 5)) +>f1 : Symbol(f1, Decl(strictFunctionTypes1.ts, 0, 0)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) + +const x2 = f2("abc", fo, fs); // "abc" +>x2 : Symbol(x2, Decl(strictFunctionTypes1.ts, 13, 5)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 0, 79)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) + +const x3 = f3("abc", fo, fx); // "abc" | "def" +>x3 : Symbol(x3, Decl(strictFunctionTypes1.ts, 14, 5)) +>f3 : Symbol(f3, Decl(strictFunctionTypes1.ts, 1, 74)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fx : Symbol(fx, Decl(strictFunctionTypes1.ts, 9, 37)) + +const x4 = f4(fo, fs); // Func +>x4 : Symbol(x4, Decl(strictFunctionTypes1.ts, 15, 5)) +>f4 : Symbol(f4, Decl(strictFunctionTypes1.ts, 4, 34)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) + diff --git a/tests/baselines/reference/strictFunctionTypes1.types b/tests/baselines/reference/strictFunctionTypes1.types new file mode 100644 index 0000000000000..9701d78cff0e3 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypes1.types @@ -0,0 +1,102 @@ +=== tests/cases/compiler/strictFunctionTypes1.ts === +declare function f1(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void; +>f1 : (f1: (x: T) => void, f2: (x: T) => void) => (x: T) => void +>T : T +>f1 : (x: T) => void +>x : T +>T : T +>f2 : (x: T) => void +>x : T +>T : T +>x : T +>T : T + +declare function f2(obj: T, f1: (x: T) => void, f2: (x: T) => void): T; +>f2 : (obj: T, f1: (x: T) => void, f2: (x: T) => void) => T +>T : T +>obj : T +>T : T +>f1 : (x: T) => void +>x : T +>T : T +>f2 : (x: T) => void +>x : T +>T : T +>T : T + +declare function f3(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T; +>f3 : (obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void) => T +>T : T +>obj : T +>T : T +>f1 : (x: T) => void +>x : T +>T : T +>f2 : (f: (x: T) => void) => void +>f : (x: T) => void +>x : T +>T : T +>T : T + +interface Func { (x: T): void } +>Func : Func +>T : T +>x : T +>T : T + +declare function f4(f1: Func, f2: Func): Func; +>f4 : (f1: Func, f2: Func) => Func +>T : T +>f1 : Func +>Func : Func +>T : T +>f2 : Func +>Func : Func +>T : T +>Func : Func +>T : T + +declare function fo(x: Object): void; +>fo : (x: Object) => void +>x : Object +>Object : Object + +declare function fs(x: string): void; +>fs : (x: string) => void +>x : string + +declare function fx(f: (x: "def") => void): void; +>fx : (f: (x: "def") => void) => void +>f : (x: "def") => void +>x : "def" + +const x1 = f1(fo, fs); // (x: string) => void +>x1 : (x: string) => void +>f1(fo, fs) : (x: string) => void +>f1 : (f1: (x: T) => void, f2: (x: T) => void) => (x: T) => void +>fo : (x: Object) => void +>fs : (x: string) => void + +const x2 = f2("abc", fo, fs); // "abc" +>x2 : "abc" +>f2("abc", fo, fs) : "abc" +>f2 : (obj: T, f1: (x: T) => void, f2: (x: T) => void) => T +>"abc" : "abc" +>fo : (x: Object) => void +>fs : (x: string) => void + +const x3 = f3("abc", fo, fx); // "abc" | "def" +>x3 : "def" | "abc" +>f3("abc", fo, fx) : "def" | "abc" +>f3 : (obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void) => T +>"abc" : "abc" +>fo : (x: Object) => void +>fx : (f: (x: "def") => void) => void + +const x4 = f4(fo, fs); // Func +>x4 : Func +>f4(fo, fs) : Func +>f4 : (f1: Func, f2: Func) => Func +>fo : (x: Object) => void +>fs : (x: string) => void + diff --git a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt new file mode 100644 index 0000000000000..2827983bd5ae1 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt @@ -0,0 +1,340 @@ +tests/cases/compiler/strictFunctionTypesErrors.ts(10,1): error TS2322: Type '(x: string) => Object' is not assignable to type '(x: Object) => Object'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(11,1): error TS2322: Type '(x: string) => string' is not assignable to type '(x: Object) => Object'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(13,1): error TS2322: Type '(x: Object) => Object' is not assignable to type '(x: Object) => string'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(14,1): error TS2322: Type '(x: string) => Object' is not assignable to type '(x: Object) => string'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(15,1): error TS2322: Type '(x: string) => string' is not assignable to type '(x: Object) => string'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(21,1): error TS2322: Type '(x: Object) => Object' is not assignable to type '(x: string) => string'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(23,1): error TS2322: Type '(x: string) => Object' is not assignable to type '(x: string) => string'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(33,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(34,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(36,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(37,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(38,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(44,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(46,1): error TS2322: Type 'Func' is not assignable to type 'Func'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(57,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(58,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(61,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, Object>'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(62,1): error TS2322: Type 'Func, string>' is not assignable to type 'Func, Object>'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(65,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(66,1): error TS2322: Type 'Func, string>' is not assignable to type 'Func, string>'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(67,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(74,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Type 'Func' is not assignable to type 'Func'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(75,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(76,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(79,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(80,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Types of parameters 'x' and 'x' are incompatible. + Type 'Object' is not assignable to type 'string'. +tests/cases/compiler/strictFunctionTypesErrors.ts(83,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Type 'Func' is not assignable to type 'Func'. +tests/cases/compiler/strictFunctionTypesErrors.ts(84,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. + Type 'Func' is not assignable to type 'Func'. +tests/cases/compiler/strictFunctionTypesErrors.ts(111,1): error TS2322: Type 'Comparer2' is not assignable to type 'Comparer2'. + Type 'Animal' is not assignable to type 'Dog'. + Property 'dog' is missing in type 'Animal'. +tests/cases/compiler/strictFunctionTypesErrors.ts(126,1): error TS2322: Type 'Crate' is not assignable to type 'Crate'. + Types of property 'onSetItem' are incompatible. + Type '(item: Dog) => void' is not assignable to type '(item: Animal) => void'. + Types of parameters 'item' and 'item' are incompatible. + Type 'Animal' is not assignable to type 'Dog'. +tests/cases/compiler/strictFunctionTypesErrors.ts(127,1): error TS2322: Type 'Crate' is not assignable to type 'Crate'. + Types of property 'item' are incompatible. + Type 'Animal' is not assignable to type 'Dog'. + + +==== tests/cases/compiler/strictFunctionTypesErrors.ts (31 errors) ==== + export {} + + + declare let f1: (x: Object) => Object; + declare let f2: (x: Object) => string; + declare let f3: (x: string) => Object; + declare let f4: (x: string) => string; + + f1 = f2; // Ok + f1 = f3; // Error + ~~ +!!! error TS2322: Type '(x: string) => Object' is not assignable to type '(x: Object) => Object'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + f1 = f4; // Error + ~~ +!!! error TS2322: Type '(x: string) => string' is not assignable to type '(x: Object) => Object'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + f2 = f1; // Error + ~~ +!!! error TS2322: Type '(x: Object) => Object' is not assignable to type '(x: Object) => string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + f2 = f3; // Error + ~~ +!!! error TS2322: Type '(x: string) => Object' is not assignable to type '(x: Object) => string'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + f2 = f4; // Error + ~~ +!!! error TS2322: Type '(x: string) => string' is not assignable to type '(x: Object) => string'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + f3 = f1; // Ok + f3 = f2; // Ok + f3 = f4; // Ok + + f4 = f1; // Error + ~~ +!!! error TS2322: Type '(x: Object) => Object' is not assignable to type '(x: string) => string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + f4 = f2; // Ok + f4 = f3; // Error + ~~ +!!! error TS2322: Type '(x: string) => Object' is not assignable to type '(x: string) => string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + type Func = (x: T) => U; + + declare let g1: Func; + declare let g2: Func; + declare let g3: Func; + declare let g4: Func; + + g1 = g2; // Ok + g1 = g3; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + g1 = g4; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + g2 = g1; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + g2 = g3; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + g2 = g4; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + g3 = g1; // Ok + g3 = g2; // Ok + g3 = g4; // Ok + + g4 = g1; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + g4 = g2; // Ok + g4 = g3; // Error + ~~ +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + declare let h1: Func, Object>; + declare let h2: Func, string>; + declare let h3: Func, Object>; + declare let h4: Func, string>; + + h1 = h2; // Ok + h1 = h3; // Ok + h1 = h4; // Ok + + h2 = h1; // Error + ~~ +!!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + h2 = h3; // Error + ~~ +!!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + h2 = h4; // Ok + + h3 = h1; // Error + ~~ +!!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, Object>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + h3 = h2; // Error + ~~ +!!! error TS2322: Type 'Func, string>' is not assignable to type 'Func, Object>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + h3 = h4; // Ok + + h4 = h1; // Error + ~~ +!!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + h4 = h2; // Error + ~~ +!!! error TS2322: Type 'Func, string>' is not assignable to type 'Func, string>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + h4 = h3; // Error + ~~ +!!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + declare let i1: Func>; + declare let i2: Func>; + declare let i3: Func>; + declare let i4: Func>; + + i1 = i2; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + i1 = i3; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + i1 = i4; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + i2 = i1; // Ok + i2 = i3; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + i2 = i4; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. + + i3 = i1; // Ok + i3 = i2; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. + i3 = i4; // Error + ~~ +!!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. + + i4 = i1; // Ok + i4 = i2; // Ok + i4 = i3; // Ok + + interface Animal { animal: void } + interface Dog extends Animal { dog: void } + interface Cat extends Animal { cat: void } + + interface Comparer1 { + compare(a: T, b: T): number; + } + + declare let animalComparer1: Comparer1; + declare let dogComparer1: Comparer1; + + animalComparer1 = dogComparer1; // Ok + dogComparer1 = animalComparer1; // Ok + + interface Comparer2 { + compare: (a: T, b: T) => number; + } + + declare let animalComparer2: Comparer2; + declare let dogComparer2: Comparer2; + + animalComparer2 = dogComparer2; // Error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'Comparer2' is not assignable to type 'Comparer2'. +!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'. +!!! error TS2322: Property 'dog' is missing in type 'Animal'. + dogComparer2 = animalComparer2; // Ok + + // Crate is invariant in --strictFunctionTypes mode + + interface Crate { + item: T; + onSetItem: (item: T) => void; + } + + declare let animalCrate: Crate; + declare let dogCrate: Crate; + + // Errors below should elaborate the reason for invariance + + animalCrate = dogCrate; // Error + ~~~~~~~~~~~ +!!! error TS2322: Type 'Crate' is not assignable to type 'Crate'. +!!! error TS2322: Types of property 'onSetItem' are incompatible. +!!! error TS2322: Type '(item: Dog) => void' is not assignable to type '(item: Animal) => void'. +!!! error TS2322: Types of parameters 'item' and 'item' are incompatible. +!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'. + dogCrate = animalCrate; // Error + ~~~~~~~~ +!!! error TS2322: Type 'Crate' is not assignable to type 'Crate'. +!!! error TS2322: Types of property 'item' are incompatible. +!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictFunctionTypesErrors.js b/tests/baselines/reference/strictFunctionTypesErrors.js new file mode 100644 index 0000000000000..2be598f0ef9c3 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesErrors.js @@ -0,0 +1,188 @@ +//// [strictFunctionTypesErrors.ts] +export {} + + +declare let f1: (x: Object) => Object; +declare let f2: (x: Object) => string; +declare let f3: (x: string) => Object; +declare let f4: (x: string) => string; + +f1 = f2; // Ok +f1 = f3; // Error +f1 = f4; // Error + +f2 = f1; // Error +f2 = f3; // Error +f2 = f4; // Error + +f3 = f1; // Ok +f3 = f2; // Ok +f3 = f4; // Ok + +f4 = f1; // Error +f4 = f2; // Ok +f4 = f3; // Error + +type Func = (x: T) => U; + +declare let g1: Func; +declare let g2: Func; +declare let g3: Func; +declare let g4: Func; + +g1 = g2; // Ok +g1 = g3; // Error +g1 = g4; // Error + +g2 = g1; // Error +g2 = g3; // Error +g2 = g4; // Error + +g3 = g1; // Ok +g3 = g2; // Ok +g3 = g4; // Ok + +g4 = g1; // Error +g4 = g2; // Ok +g4 = g3; // Error + +declare let h1: Func, Object>; +declare let h2: Func, string>; +declare let h3: Func, Object>; +declare let h4: Func, string>; + +h1 = h2; // Ok +h1 = h3; // Ok +h1 = h4; // Ok + +h2 = h1; // Error +h2 = h3; // Error +h2 = h4; // Ok + +h3 = h1; // Error +h3 = h2; // Error +h3 = h4; // Ok + +h4 = h1; // Error +h4 = h2; // Error +h4 = h3; // Error + +declare let i1: Func>; +declare let i2: Func>; +declare let i3: Func>; +declare let i4: Func>; + +i1 = i2; // Error +i1 = i3; // Error +i1 = i4; // Error + +i2 = i1; // Ok +i2 = i3; // Error +i2 = i4; // Error + +i3 = i1; // Ok +i3 = i2; // Error +i3 = i4; // Error + +i4 = i1; // Ok +i4 = i2; // Ok +i4 = i3; // Ok + +interface Animal { animal: void } +interface Dog extends Animal { dog: void } +interface Cat extends Animal { cat: void } + +interface Comparer1 { + compare(a: T, b: T): number; +} + +declare let animalComparer1: Comparer1; +declare let dogComparer1: Comparer1; + +animalComparer1 = dogComparer1; // Ok +dogComparer1 = animalComparer1; // Ok + +interface Comparer2 { + compare: (a: T, b: T) => number; +} + +declare let animalComparer2: Comparer2; +declare let dogComparer2: Comparer2; + +animalComparer2 = dogComparer2; // Error +dogComparer2 = animalComparer2; // Ok + +// Crate is invariant in --strictFunctionTypes mode + +interface Crate { + item: T; + onSetItem: (item: T) => void; +} + +declare let animalCrate: Crate; +declare let dogCrate: Crate; + +// Errors below should elaborate the reason for invariance + +animalCrate = dogCrate; // Error +dogCrate = animalCrate; // Error + + +//// [strictFunctionTypesErrors.js] +"use strict"; +exports.__esModule = true; +f1 = f2; // Ok +f1 = f3; // Error +f1 = f4; // Error +f2 = f1; // Error +f2 = f3; // Error +f2 = f4; // Error +f3 = f1; // Ok +f3 = f2; // Ok +f3 = f4; // Ok +f4 = f1; // Error +f4 = f2; // Ok +f4 = f3; // Error +g1 = g2; // Ok +g1 = g3; // Error +g1 = g4; // Error +g2 = g1; // Error +g2 = g3; // Error +g2 = g4; // Error +g3 = g1; // Ok +g3 = g2; // Ok +g3 = g4; // Ok +g4 = g1; // Error +g4 = g2; // Ok +g4 = g3; // Error +h1 = h2; // Ok +h1 = h3; // Ok +h1 = h4; // Ok +h2 = h1; // Error +h2 = h3; // Error +h2 = h4; // Ok +h3 = h1; // Error +h3 = h2; // Error +h3 = h4; // Ok +h4 = h1; // Error +h4 = h2; // Error +h4 = h3; // Error +i1 = i2; // Error +i1 = i3; // Error +i1 = i4; // Error +i2 = i1; // Ok +i2 = i3; // Error +i2 = i4; // Error +i3 = i1; // Ok +i3 = i2; // Error +i3 = i4; // Error +i4 = i1; // Ok +i4 = i2; // Ok +i4 = i3; // Ok +animalComparer1 = dogComparer1; // Ok +dogComparer1 = animalComparer1; // Ok +animalComparer2 = dogComparer2; // Error +dogComparer2 = animalComparer2; // Ok +// Errors below should elaborate the reason for invariance +animalCrate = dogCrate; // Error +dogCrate = animalCrate; // Error diff --git a/tests/baselines/reference/strictFunctionTypesErrors.symbols b/tests/baselines/reference/strictFunctionTypesErrors.symbols new file mode 100644 index 0000000000000..30faf83d87e25 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesErrors.symbols @@ -0,0 +1,402 @@ +=== tests/cases/compiler/strictFunctionTypesErrors.ts === +export {} + + +declare let f1: (x: Object) => Object; +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) +>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 3, 17)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let f2: (x: Object) => string; +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) +>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 4, 17)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let f3: (x: string) => Object; +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) +>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 5, 17)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let f4: (x: string) => string; +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) +>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 6, 17)) + +f1 = f2; // Ok +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) + +f1 = f3; // Error +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) + +f1 = f4; // Error +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) + +f2 = f1; // Error +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) + +f2 = f3; // Error +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) + +f2 = f4; // Error +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) + +f3 = f1; // Ok +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) + +f3 = f2; // Ok +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) + +f3 = f4; // Ok +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) + +f4 = f1; // Error +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) +>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 3, 11)) + +f4 = f2; // Ok +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) +>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 4, 11)) + +f4 = f3; // Error +>f4 : Symbol(f4, Decl(strictFunctionTypesErrors.ts, 6, 11)) +>f3 : Symbol(f3, Decl(strictFunctionTypesErrors.ts, 5, 11)) + +type Func = (x: T) => U; +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 24, 10)) +>U : Symbol(U, Decl(strictFunctionTypesErrors.ts, 24, 12)) +>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 24, 19)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 24, 10)) +>U : Symbol(U, Decl(strictFunctionTypesErrors.ts, 24, 12)) + +declare let g1: Func; +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let g2: Func; +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let g3: Func; +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let g4: Func; +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) + +g1 = g2; // Ok +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) + +g1 = g3; // Error +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) + +g1 = g4; // Error +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) + +g2 = g1; // Error +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) + +g2 = g3; // Error +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) + +g2 = g4; // Error +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) + +g3 = g1; // Ok +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) + +g3 = g2; // Ok +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) + +g3 = g4; // Ok +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) + +g4 = g1; // Error +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) +>g1 : Symbol(g1, Decl(strictFunctionTypesErrors.ts, 26, 11)) + +g4 = g2; // Ok +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) +>g2 : Symbol(g2, Decl(strictFunctionTypesErrors.ts, 27, 11)) + +g4 = g3; // Error +>g4 : Symbol(g4, Decl(strictFunctionTypesErrors.ts, 29, 11)) +>g3 : Symbol(g3, Decl(strictFunctionTypesErrors.ts, 28, 11)) + +declare let h1: Func, Object>; +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let h2: Func, string>; +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let h3: Func, Object>; +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let h4: Func, string>; +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) + +h1 = h2; // Ok +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) + +h1 = h3; // Ok +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) + +h1 = h4; // Ok +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) + +h2 = h1; // Error +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) + +h2 = h3; // Error +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) + +h2 = h4; // Ok +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) + +h3 = h1; // Error +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) + +h3 = h2; // Error +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) + +h3 = h4; // Ok +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) + +h4 = h1; // Error +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) +>h1 : Symbol(h1, Decl(strictFunctionTypesErrors.ts, 47, 11)) + +h4 = h2; // Error +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) +>h2 : Symbol(h2, Decl(strictFunctionTypesErrors.ts, 48, 11)) + +h4 = h3; // Error +>h4 : Symbol(h4, Decl(strictFunctionTypesErrors.ts, 50, 11)) +>h3 : Symbol(h3, Decl(strictFunctionTypesErrors.ts, 49, 11)) + +declare let i1: Func>; +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let i2: Func>; +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) + +declare let i3: Func>; +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare let i4: Func>; +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) +>Func : Symbol(Func, Decl(strictFunctionTypesErrors.ts, 22, 8)) + +i1 = i2; // Error +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) + +i1 = i3; // Error +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) + +i1 = i4; // Error +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) + +i2 = i1; // Ok +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) + +i2 = i3; // Error +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) + +i2 = i4; // Error +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) + +i3 = i1; // Ok +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) + +i3 = i2; // Error +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) + +i3 = i4; // Error +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) + +i4 = i1; // Ok +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) +>i1 : Symbol(i1, Decl(strictFunctionTypesErrors.ts, 68, 11)) + +i4 = i2; // Ok +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) +>i2 : Symbol(i2, Decl(strictFunctionTypesErrors.ts, 69, 11)) + +i4 = i3; // Ok +>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11)) +>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11)) + +interface Animal { animal: void } +>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8)) +>animal : Symbol(Animal.animal, Decl(strictFunctionTypesErrors.ts, 89, 18)) + +interface Dog extends Animal { dog: void } +>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33)) +>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8)) +>dog : Symbol(Dog.dog, Decl(strictFunctionTypesErrors.ts, 90, 30)) + +interface Cat extends Animal { cat: void } +>Cat : Symbol(Cat, Decl(strictFunctionTypesErrors.ts, 90, 42)) +>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8)) +>cat : Symbol(Cat.cat, Decl(strictFunctionTypesErrors.ts, 91, 30)) + +interface Comparer1 { +>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 42)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 93, 20)) + + compare(a: T, b: T): number; +>compare : Symbol(Comparer1.compare, Decl(strictFunctionTypesErrors.ts, 93, 24)) +>a : Symbol(a, Decl(strictFunctionTypesErrors.ts, 94, 12)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 93, 20)) +>b : Symbol(b, Decl(strictFunctionTypesErrors.ts, 94, 17)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 93, 20)) +} + +declare let animalComparer1: Comparer1; +>animalComparer1 : Symbol(animalComparer1, Decl(strictFunctionTypesErrors.ts, 97, 11)) +>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 42)) +>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8)) + +declare let dogComparer1: Comparer1; +>dogComparer1 : Symbol(dogComparer1, Decl(strictFunctionTypesErrors.ts, 98, 11)) +>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 42)) +>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33)) + +animalComparer1 = dogComparer1; // Ok +>animalComparer1 : Symbol(animalComparer1, Decl(strictFunctionTypesErrors.ts, 97, 11)) +>dogComparer1 : Symbol(dogComparer1, Decl(strictFunctionTypesErrors.ts, 98, 11)) + +dogComparer1 = animalComparer1; // Ok +>dogComparer1 : Symbol(dogComparer1, Decl(strictFunctionTypesErrors.ts, 98, 11)) +>animalComparer1 : Symbol(animalComparer1, Decl(strictFunctionTypesErrors.ts, 97, 11)) + +interface Comparer2 { +>Comparer2 : Symbol(Comparer2, Decl(strictFunctionTypesErrors.ts, 101, 31)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 103, 20)) + + compare: (a: T, b: T) => number; +>compare : Symbol(Comparer2.compare, Decl(strictFunctionTypesErrors.ts, 103, 24)) +>a : Symbol(a, Decl(strictFunctionTypesErrors.ts, 104, 14)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 103, 20)) +>b : Symbol(b, Decl(strictFunctionTypesErrors.ts, 104, 19)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 103, 20)) +} + +declare let animalComparer2: Comparer2; +>animalComparer2 : Symbol(animalComparer2, Decl(strictFunctionTypesErrors.ts, 107, 11)) +>Comparer2 : Symbol(Comparer2, Decl(strictFunctionTypesErrors.ts, 101, 31)) +>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8)) + +declare let dogComparer2: Comparer2; +>dogComparer2 : Symbol(dogComparer2, Decl(strictFunctionTypesErrors.ts, 108, 11)) +>Comparer2 : Symbol(Comparer2, Decl(strictFunctionTypesErrors.ts, 101, 31)) +>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33)) + +animalComparer2 = dogComparer2; // Error +>animalComparer2 : Symbol(animalComparer2, Decl(strictFunctionTypesErrors.ts, 107, 11)) +>dogComparer2 : Symbol(dogComparer2, Decl(strictFunctionTypesErrors.ts, 108, 11)) + +dogComparer2 = animalComparer2; // Ok +>dogComparer2 : Symbol(dogComparer2, Decl(strictFunctionTypesErrors.ts, 108, 11)) +>animalComparer2 : Symbol(animalComparer2, Decl(strictFunctionTypesErrors.ts, 107, 11)) + +// Crate is invariant in --strictFunctionTypes mode + +interface Crate { +>Crate : Symbol(Crate, Decl(strictFunctionTypesErrors.ts, 111, 31)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 115, 16)) + + item: T; +>item : Symbol(Crate.item, Decl(strictFunctionTypesErrors.ts, 115, 20)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 115, 16)) + + onSetItem: (item: T) => void; +>onSetItem : Symbol(Crate.onSetItem, Decl(strictFunctionTypesErrors.ts, 116, 12)) +>item : Symbol(item, Decl(strictFunctionTypesErrors.ts, 117, 16)) +>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 115, 16)) +} + +declare let animalCrate: Crate; +>animalCrate : Symbol(animalCrate, Decl(strictFunctionTypesErrors.ts, 120, 11)) +>Crate : Symbol(Crate, Decl(strictFunctionTypesErrors.ts, 111, 31)) +>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8)) + +declare let dogCrate: Crate; +>dogCrate : Symbol(dogCrate, Decl(strictFunctionTypesErrors.ts, 121, 11)) +>Crate : Symbol(Crate, Decl(strictFunctionTypesErrors.ts, 111, 31)) +>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33)) + +// Errors below should elaborate the reason for invariance + +animalCrate = dogCrate; // Error +>animalCrate : Symbol(animalCrate, Decl(strictFunctionTypesErrors.ts, 120, 11)) +>dogCrate : Symbol(dogCrate, Decl(strictFunctionTypesErrors.ts, 121, 11)) + +dogCrate = animalCrate; // Error +>dogCrate : Symbol(dogCrate, Decl(strictFunctionTypesErrors.ts, 121, 11)) +>animalCrate : Symbol(animalCrate, Decl(strictFunctionTypesErrors.ts, 120, 11)) + diff --git a/tests/baselines/reference/strictFunctionTypesErrors.types b/tests/baselines/reference/strictFunctionTypesErrors.types new file mode 100644 index 0000000000000..e4372d4b8fa20 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesErrors.types @@ -0,0 +1,456 @@ +=== tests/cases/compiler/strictFunctionTypesErrors.ts === +export {} + + +declare let f1: (x: Object) => Object; +>f1 : (x: Object) => Object +>x : Object +>Object : Object +>Object : Object + +declare let f2: (x: Object) => string; +>f2 : (x: Object) => string +>x : Object +>Object : Object + +declare let f3: (x: string) => Object; +>f3 : (x: string) => Object +>x : string +>Object : Object + +declare let f4: (x: string) => string; +>f4 : (x: string) => string +>x : string + +f1 = f2; // Ok +>f1 = f2 : (x: Object) => string +>f1 : (x: Object) => Object +>f2 : (x: Object) => string + +f1 = f3; // Error +>f1 = f3 : (x: string) => Object +>f1 : (x: Object) => Object +>f3 : (x: string) => Object + +f1 = f4; // Error +>f1 = f4 : (x: string) => string +>f1 : (x: Object) => Object +>f4 : (x: string) => string + +f2 = f1; // Error +>f2 = f1 : (x: Object) => Object +>f2 : (x: Object) => string +>f1 : (x: Object) => Object + +f2 = f3; // Error +>f2 = f3 : (x: string) => Object +>f2 : (x: Object) => string +>f3 : (x: string) => Object + +f2 = f4; // Error +>f2 = f4 : (x: string) => string +>f2 : (x: Object) => string +>f4 : (x: string) => string + +f3 = f1; // Ok +>f3 = f1 : (x: Object) => Object +>f3 : (x: string) => Object +>f1 : (x: Object) => Object + +f3 = f2; // Ok +>f3 = f2 : (x: Object) => string +>f3 : (x: string) => Object +>f2 : (x: Object) => string + +f3 = f4; // Ok +>f3 = f4 : (x: string) => string +>f3 : (x: string) => Object +>f4 : (x: string) => string + +f4 = f1; // Error +>f4 = f1 : (x: Object) => Object +>f4 : (x: string) => string +>f1 : (x: Object) => Object + +f4 = f2; // Ok +>f4 = f2 : (x: Object) => string +>f4 : (x: string) => string +>f2 : (x: Object) => string + +f4 = f3; // Error +>f4 = f3 : (x: string) => Object +>f4 : (x: string) => string +>f3 : (x: string) => Object + +type Func = (x: T) => U; +>Func : (x: T) => U +>T : T +>U : U +>x : T +>T : T +>U : U + +declare let g1: Func; +>g1 : (x: Object) => Object +>Func : (x: T) => U +>Object : Object +>Object : Object + +declare let g2: Func; +>g2 : (x: Object) => string +>Func : (x: T) => U +>Object : Object + +declare let g3: Func; +>g3 : (x: string) => Object +>Func : (x: T) => U +>Object : Object + +declare let g4: Func; +>g4 : (x: string) => string +>Func : (x: T) => U + +g1 = g2; // Ok +>g1 = g2 : (x: Object) => string +>g1 : (x: Object) => Object +>g2 : (x: Object) => string + +g1 = g3; // Error +>g1 = g3 : (x: string) => Object +>g1 : (x: Object) => Object +>g3 : (x: string) => Object + +g1 = g4; // Error +>g1 = g4 : (x: string) => string +>g1 : (x: Object) => Object +>g4 : (x: string) => string + +g2 = g1; // Error +>g2 = g1 : (x: Object) => Object +>g2 : (x: Object) => string +>g1 : (x: Object) => Object + +g2 = g3; // Error +>g2 = g3 : (x: string) => Object +>g2 : (x: Object) => string +>g3 : (x: string) => Object + +g2 = g4; // Error +>g2 = g4 : (x: string) => string +>g2 : (x: Object) => string +>g4 : (x: string) => string + +g3 = g1; // Ok +>g3 = g1 : (x: Object) => Object +>g3 : (x: string) => Object +>g1 : (x: Object) => Object + +g3 = g2; // Ok +>g3 = g2 : (x: Object) => string +>g3 : (x: string) => Object +>g2 : (x: Object) => string + +g3 = g4; // Ok +>g3 = g4 : (x: string) => string +>g3 : (x: string) => Object +>g4 : (x: string) => string + +g4 = g1; // Error +>g4 = g1 : (x: Object) => Object +>g4 : (x: string) => string +>g1 : (x: Object) => Object + +g4 = g2; // Ok +>g4 = g2 : (x: Object) => string +>g4 : (x: string) => string +>g2 : (x: Object) => string + +g4 = g3; // Error +>g4 = g3 : (x: string) => Object +>g4 : (x: string) => string +>g3 : (x: string) => Object + +declare let h1: Func, Object>; +>h1 : (x: Func) => Object +>Func : (x: T) => U +>Func : (x: T) => U +>Object : Object +>Object : Object + +declare let h2: Func, string>; +>h2 : (x: Func) => string +>Func : (x: T) => U +>Func : (x: T) => U +>Object : Object + +declare let h3: Func, Object>; +>h3 : (x: Func) => Object +>Func : (x: T) => U +>Func : (x: T) => U +>Object : Object + +declare let h4: Func, string>; +>h4 : (x: Func) => string +>Func : (x: T) => U +>Func : (x: T) => U + +h1 = h2; // Ok +>h1 = h2 : (x: Func) => string +>h1 : (x: Func) => Object +>h2 : (x: Func) => string + +h1 = h3; // Ok +>h1 = h3 : (x: Func) => Object +>h1 : (x: Func) => Object +>h3 : (x: Func) => Object + +h1 = h4; // Ok +>h1 = h4 : (x: Func) => string +>h1 : (x: Func) => Object +>h4 : (x: Func) => string + +h2 = h1; // Error +>h2 = h1 : (x: Func) => Object +>h2 : (x: Func) => string +>h1 : (x: Func) => Object + +h2 = h3; // Error +>h2 = h3 : (x: Func) => Object +>h2 : (x: Func) => string +>h3 : (x: Func) => Object + +h2 = h4; // Ok +>h2 = h4 : (x: Func) => string +>h2 : (x: Func) => string +>h4 : (x: Func) => string + +h3 = h1; // Error +>h3 = h1 : (x: Func) => Object +>h3 : (x: Func) => Object +>h1 : (x: Func) => Object + +h3 = h2; // Error +>h3 = h2 : (x: Func) => string +>h3 : (x: Func) => Object +>h2 : (x: Func) => string + +h3 = h4; // Ok +>h3 = h4 : (x: Func) => string +>h3 : (x: Func) => Object +>h4 : (x: Func) => string + +h4 = h1; // Error +>h4 = h1 : (x: Func) => Object +>h4 : (x: Func) => string +>h1 : (x: Func) => Object + +h4 = h2; // Error +>h4 = h2 : (x: Func) => string +>h4 : (x: Func) => string +>h2 : (x: Func) => string + +h4 = h3; // Error +>h4 = h3 : (x: Func) => Object +>h4 : (x: Func) => string +>h3 : (x: Func) => Object + +declare let i1: Func>; +>i1 : (x: Object) => Func +>Func : (x: T) => U +>Object : Object +>Func : (x: T) => U +>Object : Object + +declare let i2: Func>; +>i2 : (x: Object) => Func +>Func : (x: T) => U +>Object : Object +>Func : (x: T) => U + +declare let i3: Func>; +>i3 : (x: string) => Func +>Func : (x: T) => U +>Func : (x: T) => U +>Object : Object + +declare let i4: Func>; +>i4 : (x: string) => Func +>Func : (x: T) => U +>Func : (x: T) => U + +i1 = i2; // Error +>i1 = i2 : (x: Object) => Func +>i1 : (x: Object) => Func +>i2 : (x: Object) => Func + +i1 = i3; // Error +>i1 = i3 : (x: string) => Func +>i1 : (x: Object) => Func +>i3 : (x: string) => Func + +i1 = i4; // Error +>i1 = i4 : (x: string) => Func +>i1 : (x: Object) => Func +>i4 : (x: string) => Func + +i2 = i1; // Ok +>i2 = i1 : (x: Object) => Func +>i2 : (x: Object) => Func +>i1 : (x: Object) => Func + +i2 = i3; // Error +>i2 = i3 : (x: string) => Func +>i2 : (x: Object) => Func +>i3 : (x: string) => Func + +i2 = i4; // Error +>i2 = i4 : (x: string) => Func +>i2 : (x: Object) => Func +>i4 : (x: string) => Func + +i3 = i1; // Ok +>i3 = i1 : (x: Object) => Func +>i3 : (x: string) => Func +>i1 : (x: Object) => Func + +i3 = i2; // Error +>i3 = i2 : (x: Object) => Func +>i3 : (x: string) => Func +>i2 : (x: Object) => Func + +i3 = i4; // Error +>i3 = i4 : (x: string) => Func +>i3 : (x: string) => Func +>i4 : (x: string) => Func + +i4 = i1; // Ok +>i4 = i1 : (x: Object) => Func +>i4 : (x: string) => Func +>i1 : (x: Object) => Func + +i4 = i2; // Ok +>i4 = i2 : (x: Object) => Func +>i4 : (x: string) => Func +>i2 : (x: Object) => Func + +i4 = i3; // Ok +>i4 = i3 : (x: string) => Func +>i4 : (x: string) => Func +>i3 : (x: string) => Func + +interface Animal { animal: void } +>Animal : Animal +>animal : void + +interface Dog extends Animal { dog: void } +>Dog : Dog +>Animal : Animal +>dog : void + +interface Cat extends Animal { cat: void } +>Cat : Cat +>Animal : Animal +>cat : void + +interface Comparer1 { +>Comparer1 : Comparer1 +>T : T + + compare(a: T, b: T): number; +>compare : (a: T, b: T) => number +>a : T +>T : T +>b : T +>T : T +} + +declare let animalComparer1: Comparer1; +>animalComparer1 : Comparer1 +>Comparer1 : Comparer1 +>Animal : Animal + +declare let dogComparer1: Comparer1; +>dogComparer1 : Comparer1 +>Comparer1 : Comparer1 +>Dog : Dog + +animalComparer1 = dogComparer1; // Ok +>animalComparer1 = dogComparer1 : Comparer1 +>animalComparer1 : Comparer1 +>dogComparer1 : Comparer1 + +dogComparer1 = animalComparer1; // Ok +>dogComparer1 = animalComparer1 : Comparer1 +>dogComparer1 : Comparer1 +>animalComparer1 : Comparer1 + +interface Comparer2 { +>Comparer2 : Comparer2 +>T : T + + compare: (a: T, b: T) => number; +>compare : (a: T, b: T) => number +>a : T +>T : T +>b : T +>T : T +} + +declare let animalComparer2: Comparer2; +>animalComparer2 : Comparer2 +>Comparer2 : Comparer2 +>Animal : Animal + +declare let dogComparer2: Comparer2; +>dogComparer2 : Comparer2 +>Comparer2 : Comparer2 +>Dog : Dog + +animalComparer2 = dogComparer2; // Error +>animalComparer2 = dogComparer2 : Comparer2 +>animalComparer2 : Comparer2 +>dogComparer2 : Comparer2 + +dogComparer2 = animalComparer2; // Ok +>dogComparer2 = animalComparer2 : Comparer2 +>dogComparer2 : Comparer2 +>animalComparer2 : Comparer2 + +// Crate is invariant in --strictFunctionTypes mode + +interface Crate { +>Crate : Crate +>T : T + + item: T; +>item : T +>T : T + + onSetItem: (item: T) => void; +>onSetItem : (item: T) => void +>item : T +>T : T +} + +declare let animalCrate: Crate; +>animalCrate : Crate +>Crate : Crate +>Animal : Animal + +declare let dogCrate: Crate; +>dogCrate : Crate +>Crate : Crate +>Dog : Dog + +// Errors below should elaborate the reason for invariance + +animalCrate = dogCrate; // Error +>animalCrate = dogCrate : Crate +>animalCrate : Crate +>dogCrate : Crate + +dogCrate = animalCrate; // Error +>dogCrate = animalCrate : Crate +>dogCrate : Crate +>animalCrate : Crate + diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index a1bc2185da5ed..08887fc6c943f 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 12ce62fdefbaf..ca2b4aa408785 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index ea94f857fa48f..9437685c295c4 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 40181bc2553e6..d2e7e85ad55cd 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 228c332c1e329..3f4100033d017 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index a1bc2185da5ed..08887fc6c943f 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index a3c6771965d9d..22cb0444209e6 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 96b15f67792db..fc3321600fe96 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/cases/compiler/strictFunctionTypes1.ts b/tests/cases/compiler/strictFunctionTypes1.ts new file mode 100644 index 0000000000000..6c07bc51ffed2 --- /dev/null +++ b/tests/cases/compiler/strictFunctionTypes1.ts @@ -0,0 +1,19 @@ +// @strict: true +// @declaration: true + +declare function f1(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void; +declare function f2(obj: T, f1: (x: T) => void, f2: (x: T) => void): T; +declare function f3(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T; + +interface Func { (x: T): void } + +declare function f4(f1: Func, f2: Func): Func; + +declare function fo(x: Object): void; +declare function fs(x: string): void; +declare function fx(f: (x: "def") => void): void; + +const x1 = f1(fo, fs); // (x: string) => void +const x2 = f2("abc", fo, fs); // "abc" +const x3 = f3("abc", fo, fx); // "abc" | "def" +const x4 = f4(fo, fs); // Func diff --git a/tests/cases/compiler/strictFunctionTypesErrors.ts b/tests/cases/compiler/strictFunctionTypesErrors.ts new file mode 100644 index 0000000000000..fbf1c0fa6da92 --- /dev/null +++ b/tests/cases/compiler/strictFunctionTypesErrors.ts @@ -0,0 +1,128 @@ +export {} + +// @strict: true + +declare let f1: (x: Object) => Object; +declare let f2: (x: Object) => string; +declare let f3: (x: string) => Object; +declare let f4: (x: string) => string; + +f1 = f2; // Ok +f1 = f3; // Error +f1 = f4; // Error + +f2 = f1; // Error +f2 = f3; // Error +f2 = f4; // Error + +f3 = f1; // Ok +f3 = f2; // Ok +f3 = f4; // Ok + +f4 = f1; // Error +f4 = f2; // Ok +f4 = f3; // Error + +type Func = (x: T) => U; + +declare let g1: Func; +declare let g2: Func; +declare let g3: Func; +declare let g4: Func; + +g1 = g2; // Ok +g1 = g3; // Error +g1 = g4; // Error + +g2 = g1; // Error +g2 = g3; // Error +g2 = g4; // Error + +g3 = g1; // Ok +g3 = g2; // Ok +g3 = g4; // Ok + +g4 = g1; // Error +g4 = g2; // Ok +g4 = g3; // Error + +declare let h1: Func, Object>; +declare let h2: Func, string>; +declare let h3: Func, Object>; +declare let h4: Func, string>; + +h1 = h2; // Ok +h1 = h3; // Ok +h1 = h4; // Ok + +h2 = h1; // Error +h2 = h3; // Error +h2 = h4; // Ok + +h3 = h1; // Error +h3 = h2; // Error +h3 = h4; // Ok + +h4 = h1; // Error +h4 = h2; // Error +h4 = h3; // Error + +declare let i1: Func>; +declare let i2: Func>; +declare let i3: Func>; +declare let i4: Func>; + +i1 = i2; // Error +i1 = i3; // Error +i1 = i4; // Error + +i2 = i1; // Ok +i2 = i3; // Error +i2 = i4; // Error + +i3 = i1; // Ok +i3 = i2; // Error +i3 = i4; // Error + +i4 = i1; // Ok +i4 = i2; // Ok +i4 = i3; // Ok + +interface Animal { animal: void } +interface Dog extends Animal { dog: void } +interface Cat extends Animal { cat: void } + +interface Comparer1 { + compare(a: T, b: T): number; +} + +declare let animalComparer1: Comparer1; +declare let dogComparer1: Comparer1; + +animalComparer1 = dogComparer1; // Ok +dogComparer1 = animalComparer1; // Ok + +interface Comparer2 { + compare: (a: T, b: T) => number; +} + +declare let animalComparer2: Comparer2; +declare let dogComparer2: Comparer2; + +animalComparer2 = dogComparer2; // Error +dogComparer2 = animalComparer2; // Ok + +// Crate is invariant in --strictFunctionTypes mode + +interface Crate { + item: T; + onSetItem: (item: T) => void; +} + +declare let animalCrate: Crate; +declare let dogCrate: Crate; + +// Errors below should elaborate the reason for invariance + +animalCrate = dogCrate; // Error +dogCrate = animalCrate; // Error