Merge pull request #18654 from Microsoft/strictFunctionTypes

Strict function types
This commit is contained in:
Anders Hejlsberg 2017-10-02 23:09:17 +01:00 committed by GitHub
commit 884c72efb4
23 changed files with 1986 additions and 47 deletions

View file

@ -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 = <TypeParameter>createType(TypeFlags.TypeParameter);
const markerSubType = <TypeParameter>createType(TypeFlags.TypeParameter);
markerSubType.constraint = markerSuperType;
const markerOtherType = <TypeParameter>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);
@ -2510,7 +2516,7 @@ namespace ts {
return typeReferenceToTypeNode(<TypeReference>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);
}
@ -6724,7 +6730,7 @@ namespace ts {
}
function getConstraintDeclaration(type: TypeParameter) {
return getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter).constraint;
return type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter).constraint;
}
function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type {
@ -8536,6 +8542,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);
@ -8543,7 +8552,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) {
@ -8577,7 +8586,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,
@ -9189,7 +9198,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) {
@ -9198,11 +9207,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;
}
@ -9335,8 +9378,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)) {
@ -9365,11 +9406,34 @@ namespace ts {
}
}
else {
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
// We have type references to same target type, see if relationship holds for all type arguments
if (result = typeArgumentsRelatedTo(<TypeReference>source, <TypeReference>target, reportErrors)) {
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>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((<TypeReference>source).target);
if (result = typeArgumentsRelatedTo(<TypeReference>source, <TypeReference>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(<TypeReference>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.
@ -9780,6 +9844,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(<TypeParameter>type);
}
@ -10055,6 +10182,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 && (<TypeReference>type).target === globalArrayType;
}
@ -10581,8 +10713,14 @@ namespace ts {
const sourceTypes = (<TypeReference>source).typeArguments || emptyArray;
const targetTypes = (<TypeReference>target).typeArguments || emptyArray;
const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
const variances = getVariances((<TypeReference>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) {
@ -10653,6 +10791,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) {
@ -10730,7 +10879,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);
@ -10803,11 +10952,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.
@ -18853,7 +19004,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);
}

View file

@ -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",

View file

@ -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

View file

@ -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<TypeReference>; // Generic instantiation cache
instantiations: Map<TypeReference>; // 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;

View file

@ -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.

View file

@ -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 {

View file

@ -0,0 +1,42 @@
//// [strictFunctionTypes1.ts]
declare function f1<T>(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void;
declare function f2<T>(obj: T, f1: (x: T) => void, f2: (x: T) => void): T;
declare function f3<T>(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T;
interface Func<T> { (x: T): void }
declare function f4<T>(f1: Func<T>, f2: Func<T>): Func<T>;
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<string>
//// [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<string>
//// [strictFunctionTypes1.d.ts]
declare function f1<T>(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void;
declare function f2<T>(obj: T, f1: (x: T) => void, f2: (x: T) => void): T;
declare function f3<T>(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T;
interface Func<T> {
(x: T): void;
}
declare function f4<T>(f1: Func<T>, f2: Func<T>): Func<T>;
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<string>;

View file

@ -0,0 +1,96 @@
=== tests/cases/compiler/strictFunctionTypes1.ts ===
declare function f1<T>(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<T>(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<T>(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<T> { (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<T>(f1: Func<T>, f2: Func<T>): Func<T>;
>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<string>
>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))

View file

@ -0,0 +1,102 @@
=== tests/cases/compiler/strictFunctionTypes1.ts ===
declare function f1<T>(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void;
>f1 : <T>(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<T>(obj: T, f1: (x: T) => void, f2: (x: T) => void): T;
>f2 : <T>(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<T>(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T;
>f3 : <T>(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<T> { (x: T): void }
>Func : Func<T>
>T : T
>x : T
>T : T
declare function f4<T>(f1: Func<T>, f2: Func<T>): Func<T>;
>f4 : <T>(f1: Func<T>, f2: Func<T>) => Func<T>
>T : T
>f1 : Func<T>
>Func : Func<T>
>T : T
>f2 : Func<T>
>Func : Func<T>
>T : T
>Func : Func<T>
>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 : <T>(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 : <T>(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 : <T>(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<string>
>x4 : Func<string>
>f4(fo, fs) : Func<string>
>f4 : <T>(f1: Func<T>, f2: Func<T>) => Func<T>
>fo : (x: Object) => void
>fs : (x: string) => void

View file

@ -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<string, Object>' is not assignable to type 'Func<Object, Object>'.
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<string, string>' is not assignable to type 'Func<Object, Object>'.
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<Object, Object>' is not assignable to type 'Func<Object, string>'.
Type 'Object' is not assignable to type 'string'.
tests/cases/compiler/strictFunctionTypesErrors.ts(37,1): error TS2322: Type 'Func<string, Object>' is not assignable to type 'Func<Object, string>'.
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<string, string>' is not assignable to type 'Func<Object, string>'.
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<Object, Object>' is not assignable to type 'Func<string, string>'.
Type 'Object' is not assignable to type 'string'.
tests/cases/compiler/strictFunctionTypesErrors.ts(46,1): error TS2322: Type 'Func<string, Object>' is not assignable to type 'Func<string, string>'.
Type 'Object' is not assignable to type 'string'.
tests/cases/compiler/strictFunctionTypesErrors.ts(57,1): error TS2322: Type 'Func<Func<Object, void>, Object>' is not assignable to type 'Func<Func<Object, void>, string>'.
Type 'Object' is not assignable to type 'string'.
tests/cases/compiler/strictFunctionTypesErrors.ts(58,1): error TS2322: Type 'Func<Func<string, void>, Object>' is not assignable to type 'Func<Func<Object, void>, string>'.
Type 'Object' is not assignable to type 'string'.
tests/cases/compiler/strictFunctionTypesErrors.ts(61,1): error TS2322: Type 'Func<Func<Object, void>, Object>' is not assignable to type 'Func<Func<string, void>, 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<Func<Object, void>, string>' is not assignable to type 'Func<Func<string, void>, 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<Func<Object, void>, Object>' is not assignable to type 'Func<Func<string, void>, 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<Func<Object, void>, string>' is not assignable to type 'Func<Func<string, void>, 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<Func<string, void>, Object>' is not assignable to type 'Func<Func<string, void>, string>'.
Type 'Object' is not assignable to type 'string'.
tests/cases/compiler/strictFunctionTypesErrors.ts(74,1): error TS2322: Type 'Func<Object, Func<string, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
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<string, Func<Object, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
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<string, Func<string, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
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<string, Func<Object, void>>' is not assignable to type 'Func<Object, Func<string, void>>'.
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<string, Func<string, void>>' is not assignable to type 'Func<Object, Func<string, void>>'.
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<Object, Func<string, void>>' is not assignable to type 'Func<string, Func<Object, void>>'.
Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
tests/cases/compiler/strictFunctionTypesErrors.ts(84,1): error TS2322: Type 'Func<string, Func<string, void>>' is not assignable to type 'Func<string, Func<Object, void>>'.
Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
tests/cases/compiler/strictFunctionTypesErrors.ts(111,1): error TS2322: Type 'Comparer2<Dog>' is not assignable to type 'Comparer2<Animal>'.
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<Dog>' is not assignable to type 'Crate<Animal>'.
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<Animal>' is not assignable to type 'Crate<Dog>'.
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<T, U> = (x: T) => U;
declare let g1: Func<Object, Object>;
declare let g2: Func<Object, string>;
declare let g3: Func<string, Object>;
declare let g4: Func<string, string>;
g1 = g2; // Ok
g1 = g3; // Error
~~
!!! error TS2322: Type 'Func<string, Object>' is not assignable to type 'Func<Object, Object>'.
!!! 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<string, string>' is not assignable to type 'Func<Object, Object>'.
!!! 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<Object, Object>' is not assignable to type 'Func<Object, string>'.
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
g2 = g3; // Error
~~
!!! error TS2322: Type 'Func<string, Object>' is not assignable to type 'Func<Object, string>'.
!!! 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<string, string>' is not assignable to type 'Func<Object, string>'.
!!! 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<Object, Object>' is not assignable to type 'Func<string, string>'.
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
g4 = g2; // Ok
g4 = g3; // Error
~~
!!! error TS2322: Type 'Func<string, Object>' is not assignable to type 'Func<string, string>'.
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
declare let h1: Func<Func<Object, void>, Object>;
declare let h2: Func<Func<Object, void>, string>;
declare let h3: Func<Func<string, void>, Object>;
declare let h4: Func<Func<string, void>, string>;
h1 = h2; // Ok
h1 = h3; // Ok
h1 = h4; // Ok
h2 = h1; // Error
~~
!!! error TS2322: Type 'Func<Func<Object, void>, Object>' is not assignable to type 'Func<Func<Object, void>, string>'.
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
h2 = h3; // Error
~~
!!! error TS2322: Type 'Func<Func<string, void>, Object>' is not assignable to type 'Func<Func<Object, void>, string>'.
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
h2 = h4; // Ok
h3 = h1; // Error
~~
!!! error TS2322: Type 'Func<Func<Object, void>, Object>' is not assignable to type 'Func<Func<string, void>, 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<Func<Object, void>, string>' is not assignable to type 'Func<Func<string, void>, 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<Func<Object, void>, Object>' is not assignable to type 'Func<Func<string, void>, 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<Func<Object, void>, string>' is not assignable to type 'Func<Func<string, void>, 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<Func<string, void>, Object>' is not assignable to type 'Func<Func<string, void>, string>'.
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
declare let i1: Func<Object, Func<Object, void>>;
declare let i2: Func<Object, Func<string, void>>;
declare let i3: Func<string, Func<Object, void>>;
declare let i4: Func<string, Func<string, void>>;
i1 = i2; // Error
~~
!!! error TS2322: Type 'Func<Object, Func<string, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
!!! error TS2322: Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
!!! 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<string, Func<Object, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
!!! 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<string, Func<string, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
!!! 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<string, Func<Object, void>>' is not assignable to type 'Func<Object, Func<string, void>>'.
!!! 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<string, Func<string, void>>' is not assignable to type 'Func<Object, Func<string, void>>'.
!!! 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<Object, Func<string, void>>' is not assignable to type 'Func<string, Func<Object, void>>'.
!!! error TS2322: Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
i3 = i4; // Error
~~
!!! error TS2322: Type 'Func<string, Func<string, void>>' is not assignable to type 'Func<string, Func<Object, void>>'.
!!! error TS2322: Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
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<T> {
compare(a: T, b: T): number;
}
declare let animalComparer1: Comparer1<Animal>;
declare let dogComparer1: Comparer1<Dog>;
animalComparer1 = dogComparer1; // Ok
dogComparer1 = animalComparer1; // Ok
interface Comparer2<T> {
compare: (a: T, b: T) => number;
}
declare let animalComparer2: Comparer2<Animal>;
declare let dogComparer2: Comparer2<Dog>;
animalComparer2 = dogComparer2; // Error
~~~~~~~~~~~~~~~
!!! error TS2322: Type 'Comparer2<Dog>' is not assignable to type 'Comparer2<Animal>'.
!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'.
!!! error TS2322: Property 'dog' is missing in type 'Animal'.
dogComparer2 = animalComparer2; // Ok
// Crate<T> is invariant in --strictFunctionTypes mode
interface Crate<T> {
item: T;
onSetItem: (item: T) => void;
}
declare let animalCrate: Crate<Animal>;
declare let dogCrate: Crate<Dog>;
// Errors below should elaborate the reason for invariance
animalCrate = dogCrate; // Error
~~~~~~~~~~~
!!! error TS2322: Type 'Crate<Dog>' is not assignable to type 'Crate<Animal>'.
!!! 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<Animal>' is not assignable to type 'Crate<Dog>'.
!!! error TS2322: Types of property 'item' are incompatible.
!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'.

View file

@ -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<T, U> = (x: T) => U;
declare let g1: Func<Object, Object>;
declare let g2: Func<Object, string>;
declare let g3: Func<string, Object>;
declare let g4: Func<string, string>;
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<Func<Object, void>, Object>;
declare let h2: Func<Func<Object, void>, string>;
declare let h3: Func<Func<string, void>, Object>;
declare let h4: Func<Func<string, void>, 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<Object, Func<Object, void>>;
declare let i2: Func<Object, Func<string, void>>;
declare let i3: Func<string, Func<Object, void>>;
declare let i4: Func<string, Func<string, void>>;
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<T> {
compare(a: T, b: T): number;
}
declare let animalComparer1: Comparer1<Animal>;
declare let dogComparer1: Comparer1<Dog>;
animalComparer1 = dogComparer1; // Ok
dogComparer1 = animalComparer1; // Ok
interface Comparer2<T> {
compare: (a: T, b: T) => number;
}
declare let animalComparer2: Comparer2<Animal>;
declare let dogComparer2: Comparer2<Dog>;
animalComparer2 = dogComparer2; // Error
dogComparer2 = animalComparer2; // Ok
// Crate<T> is invariant in --strictFunctionTypes mode
interface Crate<T> {
item: T;
onSetItem: (item: T) => void;
}
declare let animalCrate: Crate<Animal>;
declare let dogCrate: Crate<Dog>;
// 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

View file

@ -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<T, U> = (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<Object, Object>;
>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<Object, string>;
>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<string, Object>;
>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<string, string>;
>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<Func<Object, void>, 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<Func<Object, void>, 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<Func<string, void>, 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<Func<string, void>, 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<Object, Func<Object, void>>;
>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<Object, Func<string, void>>;
>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<string, Func<Object, void>>;
>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<string, Func<string, void>>;
>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<T> {
>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<Animal>;
>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<Dog>;
>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<T> {
>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<Animal>;
>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<Dog>;
>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<T> is invariant in --strictFunctionTypes mode
interface Crate<T> {
>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<Animal>;
>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<Dog>;
>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))

View file

@ -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<T, U> = (x: T) => U;
>Func : (x: T) => U
>T : T
>U : U
>x : T
>T : T
>U : U
declare let g1: Func<Object, Object>;
>g1 : (x: Object) => Object
>Func : (x: T) => U
>Object : Object
>Object : Object
declare let g2: Func<Object, string>;
>g2 : (x: Object) => string
>Func : (x: T) => U
>Object : Object
declare let g3: Func<string, Object>;
>g3 : (x: string) => Object
>Func : (x: T) => U
>Object : Object
declare let g4: Func<string, string>;
>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<Func<Object, void>, Object>;
>h1 : (x: Func) => Object
>Func : (x: T) => U
>Func : (x: T) => U
>Object : Object
>Object : Object
declare let h2: Func<Func<Object, void>, string>;
>h2 : (x: Func) => string
>Func : (x: T) => U
>Func : (x: T) => U
>Object : Object
declare let h3: Func<Func<string, void>, Object>;
>h3 : (x: Func) => Object
>Func : (x: T) => U
>Func : (x: T) => U
>Object : Object
declare let h4: Func<Func<string, void>, 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<Object, Func<Object, void>>;
>i1 : (x: Object) => Func
>Func : (x: T) => U
>Object : Object
>Func : (x: T) => U
>Object : Object
declare let i2: Func<Object, Func<string, void>>;
>i2 : (x: Object) => Func
>Func : (x: T) => U
>Object : Object
>Func : (x: T) => U
declare let i3: Func<string, Func<Object, void>>;
>i3 : (x: string) => Func
>Func : (x: T) => U
>Func : (x: T) => U
>Object : Object
declare let i4: Func<string, Func<string, void>>;
>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<T> {
>Comparer1 : Comparer1<T>
>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<Animal>;
>animalComparer1 : Comparer1<Animal>
>Comparer1 : Comparer1<T>
>Animal : Animal
declare let dogComparer1: Comparer1<Dog>;
>dogComparer1 : Comparer1<Dog>
>Comparer1 : Comparer1<T>
>Dog : Dog
animalComparer1 = dogComparer1; // Ok
>animalComparer1 = dogComparer1 : Comparer1<Dog>
>animalComparer1 : Comparer1<Animal>
>dogComparer1 : Comparer1<Dog>
dogComparer1 = animalComparer1; // Ok
>dogComparer1 = animalComparer1 : Comparer1<Animal>
>dogComparer1 : Comparer1<Dog>
>animalComparer1 : Comparer1<Animal>
interface Comparer2<T> {
>Comparer2 : Comparer2<T>
>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<Animal>;
>animalComparer2 : Comparer2<Animal>
>Comparer2 : Comparer2<T>
>Animal : Animal
declare let dogComparer2: Comparer2<Dog>;
>dogComparer2 : Comparer2<Dog>
>Comparer2 : Comparer2<T>
>Dog : Dog
animalComparer2 = dogComparer2; // Error
>animalComparer2 = dogComparer2 : Comparer2<Dog>
>animalComparer2 : Comparer2<Animal>
>dogComparer2 : Comparer2<Dog>
dogComparer2 = animalComparer2; // Ok
>dogComparer2 = animalComparer2 : Comparer2<Animal>
>dogComparer2 : Comparer2<Dog>
>animalComparer2 : Comparer2<Animal>
// Crate<T> is invariant in --strictFunctionTypes mode
interface Crate<T> {
>Crate : Crate<T>
>T : T
item: T;
>item : T
>T : T
onSetItem: (item: T) => void;
>onSetItem : (item: T) => void
>item : T
>T : T
}
declare let animalCrate: Crate<Animal>;
>animalCrate : Crate<Animal>
>Crate : Crate<T>
>Animal : Animal
declare let dogCrate: Crate<Dog>;
>dogCrate : Crate<Dog>
>Crate : Crate<T>
>Dog : Dog
// Errors below should elaborate the reason for invariance
animalCrate = dogCrate; // Error
>animalCrate = dogCrate : Crate<Dog>
>animalCrate : Crate<Animal>
>dogCrate : Crate<Dog>
dogCrate = animalCrate; // Error
>dogCrate = animalCrate : Crate<Animal>
>dogCrate : Crate<Dog>
>animalCrate : Crate<Animal>

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -0,0 +1,19 @@
// @strict: true
// @declaration: true
declare function f1<T>(f1: (x: T) => void, f2: (x: T) => void): (x: T) => void;
declare function f2<T>(obj: T, f1: (x: T) => void, f2: (x: T) => void): T;
declare function f3<T>(obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void): T;
interface Func<T> { (x: T): void }
declare function f4<T>(f1: Func<T>, f2: Func<T>): Func<T>;
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<string>

View file

@ -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<T, U> = (x: T) => U;
declare let g1: Func<Object, Object>;
declare let g2: Func<Object, string>;
declare let g3: Func<string, Object>;
declare let g4: Func<string, string>;
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<Func<Object, void>, Object>;
declare let h2: Func<Func<Object, void>, string>;
declare let h3: Func<Func<string, void>, Object>;
declare let h4: Func<Func<string, void>, 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<Object, Func<Object, void>>;
declare let i2: Func<Object, Func<string, void>>;
declare let i3: Func<string, Func<Object, void>>;
declare let i4: Func<string, Func<string, void>>;
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<T> {
compare(a: T, b: T): number;
}
declare let animalComparer1: Comparer1<Animal>;
declare let dogComparer1: Comparer1<Dog>;
animalComparer1 = dogComparer1; // Ok
dogComparer1 = animalComparer1; // Ok
interface Comparer2<T> {
compare: (a: T, b: T) => number;
}
declare let animalComparer2: Comparer2<Animal>;
declare let dogComparer2: Comparer2<Dog>;
animalComparer2 = dogComparer2; // Error
dogComparer2 = animalComparer2; // Ok
// Crate<T> is invariant in --strictFunctionTypes mode
interface Crate<T> {
item: T;
onSetItem: (item: T) => void;
}
declare let animalCrate: Crate<Animal>;
declare let dogCrate: Crate<Dog>;
// Errors below should elaborate the reason for invariance
animalCrate = dogCrate; // Error
dogCrate = animalCrate; // Error