Remove circular default check

This commit is contained in:
Ron Buckton
2017-01-23 19:36:02 -08:00
parent fd228a93a7
commit 15232fe17c
10 changed files with 5211 additions and 1127 deletions
+23 -82
View File
@@ -375,7 +375,6 @@ namespace ts {
ResolvedBaseConstructorType,
DeclaredType,
ResolvedReturnType,
ResolvedDefault
}
const builtinGlobals = createMap<Symbol>();
@@ -2651,7 +2650,7 @@ namespace ts {
writeSpace(writer);
buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack);
}
const defaultType = getDefaultOfTypeParameter(tp);
const defaultType = getDefaultFromTypeParameter(tp);
if (defaultType) {
writeSpace(writer);
writePunctuation(writer, SyntaxKind.EqualsToken);
@@ -3054,9 +3053,6 @@ namespace ts {
if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
return (<Signature>target).resolvedReturnType;
}
if (propertyName === TypeSystemPropertyName.ResolvedDefault) {
return (<TypeVariable>target).resolvedDefault;
}
Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
}
@@ -4863,69 +4859,6 @@ namespace ts {
return typeParameter.default === noConstraintOrDefaultType ? undefined : typeParameter.default;
}
/**
* Gets the default type for a type parameter.
*
* If the type parameter is the result of an instantiation, this gets the instantiated
* default type of its target. If the type parameter has no default type, or if the default
* type circularly references the type parameter, `undefined` is returned.
*
* This function *does* perform a circularity check.
*/
function getDefaultOfTypeParameter(typeParameter: TypeParameter): Type | undefined {
return hasNonCircularDefault(typeParameter) ? getDefaultFromTypeParameter(typeParameter) : undefined;
}
/**
* Determines whether a type parameter has a non-circular default type.
*
* Note that this function also returns `true` if a type parameter *does not* have a
* default type.
*/
function hasNonCircularDefault(typeParameter: TypeParameter): boolean {
return getResolvedDefault(typeParameter) !== circularConstraintOrDefaultType;
}
/**
* Resolves the default type of a type parameter.
*
* If the type parameter has no default, the `noConstraintOrDefaultType` singleton is
* returned. If the type parameter has a circular default, the
* `circularConstraintOrDefaultType` singleton is returned.
*/
function getResolvedDefault(typeParameter: TypeParameter): Type {
if (!typeParameter.resolvedDefault) {
if (!pushTypeResolution(typeParameter, TypeSystemPropertyName.ResolvedDefault)) {
return circularConstraintOrDefaultType;
}
const defaultType = getDefaultFromTypeParameter(typeParameter);
const type = defaultType && getResolvedDefaultWorker(defaultType);
if (!popTypeResolution()) {
return typeParameter.resolvedDefault = circularConstraintOrDefaultType;
}
typeParameter.resolvedDefault = type || noConstraintOrDefaultType;
}
return typeParameter.resolvedDefault;
}
/**
* Recursively resolves the default type for a type.
*
* If the type is a union or intersection type and any of its constituents is a circular
* reference, the `circularConstraintOrDefaultType` singleton is returned.
*/
function getResolvedDefaultWorker(type: Type): Type {
if (type.flags & TypeFlags.TypeParameter) {
return getResolvedDefault(<TypeParameter>type);
}
if (type.flags & TypeFlags.UnionOrIntersection) {
const types = map((<UnionOrIntersectionType>type).types, getResolvedDefaultWorker);
return some(types, x => x === circularConstraintOrDefaultType) ? circularConstraintOrDefaultType :
type.flags & TypeFlags.Union ? getUnionType(types) : getIntersectionType(types);
}
return type;
}
/**
* For a type parameter, return the base constraint of the type parameter. For the string, number,
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -5241,20 +5174,23 @@ namespace ts {
typeArguments = [];
}
// Map an unsatisfied type parameter with a default type to the default type.
// Map an unsatisfied type parameter with a default type.
// If a type parameter does not have a default type, or if the default type
// is a circular reference, the empty object type is used.
// is a forward reference, the empty object type is used.
const mapper: TypeMapper = t => {
const i = indexOf(typeParameters, t);
return i >= 0
? typeArguments[i] || (typeArguments[i] =
instantiateType(getDefaultOfTypeParameter(typeParameters[i]), mapper) ||
emptyObjectType)
: t;
if (i >= typeArguments.length) {
return emptyObjectType;
}
if (i >= 0) {
return typeArguments[i];
}
return t;
};
for (let i = numTypeArguments; i < numTypeParameters; i++) {
instantiateType(typeParameters[i], mapper);
const defaultType = getDefaultFromTypeParameter(typeParameters[i]);
typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : emptyObjectType;
}
}
}
@@ -9181,8 +9117,16 @@ namespace ts {
// succeeds, meaning there is no error for not having inference candidates. An
// inference error only occurs when there are *conflicting* candidates, i.e.
// candidates with no common supertype.
const defaultType = getDefaultOfTypeParameter(context.signature.typeParameters[index]);
inferredType = defaultType ? instantiateType(defaultType, getInferenceMapper(context)) : emptyObjectType;
const defaultType = getDefaultFromTypeParameter(context.signature.typeParameters[index]);
if (defaultType) {
const backreferenceMapper: TypeMapper = t => indexOf(context.signature.typeParameters, t) >= index ? emptyObjectType : t;
const mapper = combineTypeMappers(backreferenceMapper, getInferenceMapper(context));
inferredType = instantiateType(defaultType, mapper);
}
else {
inferredType = emptyObjectType;
}
inferenceSucceeded = true;
}
context.inferredTypes[index] = inferredType;
@@ -15574,11 +15518,8 @@ namespace ts {
if (!hasNonCircularBaseConstraint(typeParameter)) {
error(node.constraint, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
}
if (!hasNonCircularDefault(typeParameter)) {
error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
}
const constraintType = getConstraintOfTypeParameter(typeParameter);
const defaultType = getDefaultOfTypeParameter(typeParameter);
const defaultType = getDefaultFromTypeParameter(typeParameter);
if (constraintType && defaultType) {
checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
}
+1 -5
View File
@@ -2043,11 +2043,7 @@
"category": "Error",
"code": 2705
},
"Type parameter '{0}' has a circular default.": {
"category": "Error",
"code": 2706
},
"Generic type '{0}' requires between {1} and {2} type arguments.": {
"Generic type '{0}' requires between {1} and {2} type arguments.": {
"category": "Error",
"code": 2707
},
-2
View File
@@ -2990,8 +2990,6 @@ namespace ts {
/* @internal */
resolvedBaseConstraint: Type;
/* @internal */
resolvedDefault: Type;
/* @internal */
resolvedIndexType: IndexType;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,88 +1,42 @@
tests/cases/compiler/genericDefaultsErrors.ts(4,26): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(5,26): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(5,33): error TS2706: Type parameter 'U' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(6,29): error TS2705: Required type parameters may not follow optional type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(7,41): error TS2344: Type 'number' does not satisfy the constraint 'string'.
tests/cases/compiler/genericDefaultsErrors.ts(8,59): error TS2344: Type 'T' does not satisfy the constraint 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(4,41): error TS2344: Type 'number' does not satisfy the constraint 'string'.
tests/cases/compiler/genericDefaultsErrors.ts(5,59): error TS2344: Type 'T' does not satisfy the constraint 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(9,44): error TS2344: Type 'T' does not satisfy the constraint 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(10,39): error TS2344: Type 'number' does not satisfy the constraint 'T'.
tests/cases/compiler/genericDefaultsErrors.ts(11,26): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(11,33): error TS2706: Type parameter 'U' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(12,26): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(12,33): error TS2706: Type parameter 'U' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(13,26): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(13,33): error TS2706: Type parameter 'U' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(14,26): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(14,33): error TS2706: Type parameter 'U' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(18,1): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/genericDefaultsErrors.ts(21,1): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/genericDefaultsErrors.ts(25,13): error TS2345: Argument of type '"a"' is not assignable to parameter of type 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(28,11): error TS2428: All declarations of 'i00' must have identical type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(31,11): error TS2428: All declarations of 'i01' must have identical type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(33,19): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(34,19): error TS2706: Type parameter 'T' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(34,26): error TS2706: Type parameter 'U' has a circular default.
tests/cases/compiler/genericDefaultsErrors.ts(35,22): error TS2705: Required type parameters may not follow optional type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(36,34): error TS2344: Type 'number' does not satisfy the constraint 'string'.
tests/cases/compiler/genericDefaultsErrors.ts(37,52): error TS2344: Type 'T' does not satisfy the constraint 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(6,44): error TS2344: Type 'T' does not satisfy the constraint 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(7,39): error TS2344: Type 'number' does not satisfy the constraint 'T'.
tests/cases/compiler/genericDefaultsErrors.ts(11,1): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/genericDefaultsErrors.ts(14,1): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/genericDefaultsErrors.ts(18,13): error TS2345: Argument of type '"a"' is not assignable to parameter of type 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(21,11): error TS2428: All declarations of 'i00' must have identical type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(24,11): error TS2428: All declarations of 'i01' must have identical type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(26,27): error TS2705: Required type parameters may not follow optional type parameters.
tests/cases/compiler/genericDefaultsErrors.ts(27,34): error TS2344: Type 'number' does not satisfy the constraint 'string'.
tests/cases/compiler/genericDefaultsErrors.ts(28,52): error TS2344: Type 'T' does not satisfy the constraint 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(38,37): error TS2344: Type 'T' does not satisfy the constraint 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(39,32): error TS2344: Type 'number' does not satisfy the constraint 'T'.
tests/cases/compiler/genericDefaultsErrors.ts(42,15): error TS2707: Generic type 'i09<T, U, V>' requires between 2 and 3 type arguments.
tests/cases/compiler/genericDefaultsErrors.ts(43,15): error TS2707: Generic type 'i09<T, U, V>' requires between 2 and 3 type arguments.
tests/cases/compiler/genericDefaultsErrors.ts(46,15): error TS2707: Generic type 'i09<T, U, V>' requires between 2 and 3 type arguments.
tests/cases/compiler/genericDefaultsErrors.ts(48,17): error TS2367: Type parameter 'T' cannot be referenced outside of a declaration that defines it.
tests/cases/compiler/genericDefaultsErrors.ts(29,37): error TS2344: Type 'T' does not satisfy the constraint 'number'.
tests/cases/compiler/genericDefaultsErrors.ts(30,32): error TS2344: Type 'number' does not satisfy the constraint 'T'.
tests/cases/compiler/genericDefaultsErrors.ts(33,15): error TS2707: Generic type 'i09<T, U, V>' requires between 2 and 3 type arguments.
tests/cases/compiler/genericDefaultsErrors.ts(34,15): error TS2707: Generic type 'i09<T, U, V>' requires between 2 and 3 type arguments.
tests/cases/compiler/genericDefaultsErrors.ts(37,15): error TS2707: Generic type 'i09<T, U, V>' requires between 2 and 3 type arguments.
tests/cases/compiler/genericDefaultsErrors.ts(39,17): error TS2367: Type parameter 'T' cannot be referenced outside of a declaration that defines it.
==== tests/cases/compiler/genericDefaultsErrors.ts (33 errors) ====
==== tests/cases/compiler/genericDefaultsErrors.ts (18 errors) ====
declare const x: any;
declare function f00<T = T>(): void;
~
!!! error TS2706: Type parameter 'T' has a circular default.
declare function f01<T = U, U = T>(): void;
~
!!! error TS2706: Type parameter 'T' has a circular default.
~
!!! error TS2706: Type parameter 'U' has a circular default.
declare function f02<T = U, U>();
~
!!! error TS2705: Required type parameters may not follow optional type parameters.
declare function f03<T extends string = number>(): void;
declare function f03<T extends string = number>(): void; // error
~~~~~~
!!! error TS2344: Type 'number' does not satisfy the constraint 'string'.
declare function f04<T extends string, U extends number = T>(): void;
declare function f04<T extends string, U extends number = T>(): void; // error
~
!!! error TS2344: Type 'T' does not satisfy the constraint 'number'.
!!! error TS2344: Type 'string' is not assignable to type 'number'.
declare function f05<T, U extends number = T>(): void;
declare function f05<T, U extends number = T>(): void; // error
~
!!! error TS2344: Type 'T' does not satisfy the constraint 'number'.
declare function f06<T, U extends T = number>(): void;
declare function f06<T, U extends T = number>(): void; // error
~~~~~~
!!! error TS2344: Type 'number' does not satisfy the constraint 'T'.
declare function f07<T = U, U = T | { a: number }>(): void;
~
!!! error TS2706: Type parameter 'T' has a circular default.
~~~~~~~~~~~~~~~~~
!!! error TS2706: Type parameter 'U' has a circular default.
declare function f08<T = U, U = T & { a: number }>(): void;
~
!!! error TS2706: Type parameter 'T' has a circular default.
~~~~~~~~~~~~~~~~~
!!! error TS2706: Type parameter 'U' has a circular default.
declare function f09<T = U, U = T | { a: number }>(): void;
~
!!! error TS2706: Type parameter 'T' has a circular default.
~~~~~~~~~~~~~~~~~
!!! error TS2706: Type parameter 'U' has a circular default.
declare function f10<T = U, U = T & { a: number }>(): void;
~
!!! error TS2706: Type parameter 'T' has a circular default.
~~~~~~~~~~~~~~~~~
!!! error TS2706: Type parameter 'U' has a circular default.
declare function f11<T, U, V = number>(): void;
f11(); // ok
@@ -111,16 +65,8 @@ tests/cases/compiler/genericDefaultsErrors.ts(48,17): error TS2367: Type paramet
~~~
!!! error TS2428: All declarations of 'i01' must have identical type parameters.
interface i02<T = T> { } // error
~
!!! error TS2706: Type parameter 'T' has a circular default.
interface i03<T = U, U = T> { } // error
~
!!! error TS2706: Type parameter 'T' has a circular default.
~
!!! error TS2706: Type parameter 'U' has a circular default.
interface i04<T = U, U> { } // error
~
interface i04<T = number, U> { } // error
~
!!! error TS2705: Required type parameters may not follow optional type parameters.
interface i05<T extends string = number> { } // error
~~~~~~
@@ -2,17 +2,10 @@
declare const x: any;
declare function f00<T = T>(): void;
declare function f01<T = U, U = T>(): void;
declare function f02<T = U, U>();
declare function f03<T extends string = number>(): void;
declare function f04<T extends string, U extends number = T>(): void;
declare function f05<T, U extends number = T>(): void;
declare function f06<T, U extends T = number>(): void;
declare function f07<T = U, U = T | { a: number }>(): void;
declare function f08<T = U, U = T & { a: number }>(): void;
declare function f09<T = U, U = T | { a: number }>(): void;
declare function f10<T = U, U = T & { a: number }>(): void;
declare function f03<T extends string = number>(): void; // error
declare function f04<T extends string, U extends number = T>(): void; // error
declare function f05<T, U extends number = T>(): void; // error
declare function f06<T, U extends T = number>(): void; // error
declare function f11<T, U, V = number>(): void;
f11(); // ok
@@ -31,9 +24,7 @@ interface i00<U = number> { } // error
interface i01<T = number> { } // ok
interface i01<T = string> { } // error
interface i02<T = T> { } // error
interface i03<T = U, U = T> { } // error
interface i04<T = U, U> { } // error
interface i04<T = number, U> { } // error
interface i05<T extends string = number> { } // error
interface i06<T extends string, U extends number = T> { } // error
interface i07<T, U extends number = T> { } // error
@@ -61,25 +52,10 @@ f12("a"); // error
//// [genericDefaultsErrors.d.ts]
declare const x: any;
declare function f00<T = T>(): void;
declare function f01<T = U, U = T>(): void;
declare function f02<T = U, U>(): any;
declare function f03<T extends string = number>(): void;
declare function f04<T extends string, U extends number = T>(): void;
declare function f05<T, U extends number = T>(): void;
declare function f06<T, U extends T = number>(): void;
declare function f07<T = U, U = T | {
a: number;
}>(): void;
declare function f08<T = U, U = T & {
a: number;
}>(): void;
declare function f09<T = U, U = T | {
a: number;
}>(): void;
declare function f10<T = U, U = T & {
a: number;
}>(): void;
declare function f11<T, U, V = number>(): void;
declare function f12<T, U = T>(a?: U): void;
interface i00<T> {
@@ -90,11 +66,7 @@ interface i01<T = number> {
}
interface i01<T = string> {
}
interface i02<T = T> {
}
interface i03<T = U, U = T> {
}
interface i04<T = U, U> {
interface i04<T = number, U> {
}
interface i05<T extends string = number> {
}
+396 -57
View File
@@ -1,68 +1,398 @@
// @declaration: true
interface A { a: number; }
interface B { b: number; }
interface C { c: number; }
interface D { d: number; }
interface AB { a: number; b: number; }
interface BC { b: number; c: number; }
declare const a: A;
declare const b: B;
declare const c: C;
declare const d: D;
declare const ab: AB;
declare const bc: BC;
declare const x: any;
declare function f00<T = number>(a?: T): T;
const f00c00 = f00();
const f00c01 = f00(1);
const f00c02 = f00("a");
const f00c03 = f00<number>();
const f00c04 = f00<number>(1);
const f00c05 = f00<string>("a");
// function without type parameters
declare function f00(a?: A): A;
// no inference
f00();
f00(a);
declare function f01<T, U = T>(a?: T, b?: U): [T, U];
const f01c00 = f01();
const f01c01 = f01(1);
const f01c02 = f01(1, "a");
const f01c03 = f01<number>();
const f01c04 = f01<number>(1);
const f01c05 = f01<number>(1, 2);
const f01c06 = f01<number, string>();
const f01c07 = f01<number, string>(1);
const f01c08 = f01<number, string>(1, "a");
// function with a type parameter without a default
declare function f01<T>(a?: T): T;
// inference
f01();
f01(a);
// no inference, fully supplied
f01<A>();
f01<A>(a);
declare function f02<T extends number, U = T>(a?: T, b?: U): [T, U];
const f02c00 = f02();
const f02c01 = f02(1);
const f02c02 = f02(1, "a");
const f02c03 = f02<number>();
const f02c04 = f02<number>(1);
const f02c05 = f02<number>(1, 2);
const f02c06 = f02<number, string>();
const f02c07 = f02<number, string>(1);
const f02c08 = f02<number, string>(1, "a");
// function with a type paramter with a default
declare function f02<T = A>(a?: T): T;
// inference
f02();
f02(a);
f02(b);
// no inference, fully supplied
f02<A>();
f02<A>(a);
f02<B>();
f02<B>(b);
declare function f03<T extends number, U extends T = T>(a?: T, b?: U): [T, U];
const f03c00 = f03();
const f03c01 = f03(1);
const f03c02 = f03(1, 1);
const f03c03 = f03<number>();
const f03c04 = f03<number>(1);
const f03c05 = f03<number>(1, 2);
const f03c06 = f03<number, number>();
const f03c07 = f03<number, number>(1);
const f03c08 = f03<number, number>(1, 2);
// function with a type parameter with a default that refers to itself
declare function f03<T = T>(a?: T): T;
// inference
f03();
f03(a);
f03(b);
// no inference, fully supplied
f03<A>();
f03<A>(a);
f03<B>();
f03<B>(b);
declare function f04<T, U = T | { a: number }>(a?: T, b?: U): [T, U];
const f04c00 = f04();
const f04c01 = f04(1);
const f04c02 = f04(1, 1);
const f04c03 = f04<number>();
const f04c04 = f04<number>(1);
const f04c05 = f04<number>(1, 2);
const f04c06 = f04<number, number>();
const f04c07 = f04<number, number>(1);
const f04c08 = f04<number, number>(1, 2);
// function with a type paramter without a default and a type parameter with a default
declare function f04<T, U = B>(a?: T, b?: U): [T, U];
// inference
f04();
f04(a);
f04(a, b);
f04(a, c);
// no inference, partially supplied
f04<A>();
f04<A>(a);
f04<A>(a, b);
// no inference, fully supplied
f04<A, B>();
f04<A, B>(a);
f04<A, B>(a, b);
f04<A, C>();
f04<A, C>(a);
f04<A, C>(a, c);
declare function f05<T, U = T & { b: number }>(a?: T, b?: U): [T, U];
const f05c00 = f05();
const f05c01 = f05(1);
const f05c02 = f05(1, 1);
const f05c03 = f05<number>();
const f05c04 = f05<number>(1);
const f05c05 = f05<{ a: number }>({ a: 1 }, { a: 2, b: 3});
const f05c06 = f05<number, number>();
const f05c07 = f05<number, number>(1);
const f05c08 = f05<number, number>(1, 2);
// function with a type parameter without a default and a type parameter with a default that refers to an earlier type parameter
declare function f05<T, U = T>(a?: T, b?: U): [T, U];
// inference
f05();
f05(a);
f05(a, a);
f05(a, b);
// no inference, partially supplied
f05<A>();
f05<A>(a);
f05<A>(a, a);
// no inference, fully supplied
f05<A, B>();
f05<A, B>(a);
f05<A, B>(a, b);
// function with a type parameter with a default that refers to an earlier type parameter with a default
declare function f06<T = A, U = T>(a?: T, b?: U): [T, U];
// inference
f06();
f06(a);
f06(a, a);
f06(a, b);
f06(b, a);
f06(b, b);
// no inference, partially supplied
f06<A>();
f06<A>(a);
f06<A>(a, a);
f06<B>();
f06<B>(b);
f06<B>(b, b);
// no inference, fully supplied
f06<A, B>();
f06<A, B>(a);
f06<A, B>(a, b);
f06<B, C>();
f06<B, C>(b);
f06<B, C>(b, c);
// function with a type parameter without a default and a type parameter with a default that refers to an earlier type parameter with a default
declare function f07<T, U = B, V = U>(a?: T, b?: U, c?: V): [T, U, V];
// inference
f07();
f07(a, b);
f07(a, c);
f07(a, b, b);
f07(a, b, c);
f07(a, c, b);
f07(a, c, c);
// no inference, partially supplied
f07<A>();
f07<A>(a);
f07<A>(a, b);
f07<A>(a, b, b);
f07<A, B>();
f07<A, B>(a);
f07<A, B>(a, b);
f07<A, B>(a, b, b);
f07<A, C>();
f07<A, C>(a);
f07<A, C>(a, c);
f07<A, C>(a, c, c);
// no inference, fully supplied
f07<A, B, C>();
f07<A, B, C>(a);
f07<A, B, C>(a, b);
f07<A, B, C>(a, b, c);
f07<A, C, A>();
f07<A, C, A>(a);
f07<A, C, D>(a, c);
f07<A, C, D>(a, c, d);
// function with a type parameter with a default that refers to an earlier type parameter with a constraint
declare function f08<T extends A, U = T>(a?: T, b?: U): [T, U];
// inference
f08();
f08(a);
f08(a, a);
f08(a, b);
// no inference, partially supplied
f08<A>();
f08<A>(a);
f08<A>(a, a);
// no inference, fully supplied
f08<A, B>();
f08<A, B>(a);
f08<A, B>(a, b);
// function with a type parameter with a constraint and a default that refers to an earlier type parameter
declare function f09<T, U extends T = T>(a?: T, b?: U): [T, U];
// inference
f09();
f09(a);
f09(a, a);
f09(a, ab);
// no inference, partially supplied
f09<A>();
f09<A>(a);
f09<A>(a, a);
f09<A>(a, ab);
// no inference, fully supplied
f09<A, AB>();
f09<A, AB>(a);
f09<A, AB>(a, ab);
// function with a type parameter with a constraint and a default that refers to an earlier type parameter with a constraint
declare function f10<T extends A, U extends T = T>(a?: T, b?: U): [T, U];
// inference
f10();
f10(a);
f10(a, a);
f10(a, ab);
// no inference, partially supplied
f10<A>();
f10<A>(a);
f10<A>(a, a);
f10<A>(a, ab);
// no inference, fully supplied
f10<A, A>();
f10<A, A>(a);
f10<A, A>(a, a);
f10<A, A>(a, ab);
f10<A, AB>();
f10<A, AB>(a);
f10<A, AB>(a, ab);
// function with a type parameter with a default that refers to an earier type parameter in a union
declare function f11<T, U = T | B>(a?: T, b?: U): [T, U];
// inference
f11();
f11(a);
f11(a, a);
f11(a, b);
f11(a, c);
// no inference, partially supplied
f11<A>();
f11<A>(a);
f11<A>(a, a);
f11<A>(a, b);
// no inference, fully supplied
f11<A, C>();
f11<A, C>(a);
f11<A, C>(a, c);
// function with a type parameter with a default that refers to an earlier type parameter in an intersection
declare function f12<T, U = T & B>(a?: T, b?: U): [T, U];
// inference
f12();
f12(a);
f12(a, a);
f12(a, b);
f12(a, c);
// no inference, partially supplied
f12<A>();
f12<A>(a);
f12<A>(a, ab);
// no inference, fully supplied
f12<A, C>();
f12<A, C>(a);
f12<A, C>(a, c);
// function with a type parameter with a default that refers to a later type parameter with a default
declare function f13<T = U, U = B>(a?: T, b?: U): [T, U];
// inference
f13();
f13(a);
f13(a, b);
f13(a, c);
// no inference, partially supplied
f13<A>();
f13<A>(a);
f13<A>(a, b);
// no inference, fully supplied
f13<A, C>();
f13<A, C>(a);
f13<A, C>(a, c);
f13<A, C>(a, c);
// function with a type parameter without a default and a type parameter with a default that refers to a later type parameter with a default
declare function f14<T, U = V, V = C>(a?: T, b?: U, c?: V): [T, U, V];
// inference
f14();
f14(a);
f14(a, b);
f14(a, b, c);
f14(a, b, d);
// no inference, partially supplied
f14<A>();
f14<A>(a);
f14<A>(a, b);
f14<A>(a, b, c);
f14<A, B>();
f14<A, B>(a);
f14<A, B>(a, b);
f14<A, B>(a, b, c);
// no inference fully supplied
f14<A, B, D>();
f14<A, B, D>(a);
f14<A, B, D>(a, b);
f14<A, B, D>(a, b, d);
// function with two type parameters with defaults that mutually refer to each other
declare function f15<T = U, U = T>(a?: T, b?: U): [T, U];
// inference
f15();
f15(a);
f15(a, b);
// no inference, partially supplied
f15<A>();
f15<A>(a);
f15<A>(a, a);
// no inference, fully supplied
f15<A, B>();
f15<A, B>(a);
f15<A, B>(a, b);
// function with a type parameter without a default and two type parameters with defaults that mutually refer to each other
declare function f16<T, U = V, V = U>(a?: T, b?: U, c?: V): [T, U, V];
// no inference
f16();
f16(a);
f16(a, b);
f16(a, b, b);
// no inference, partially supplied
f16<A>();
f16<A>(a);
f16<A>(a, b);
f16<A>(a, b, b);
f16<A, B>();
f16<A, B>(a);
f16<A, B>(a, b);
f16<A, B>(a, b, b);
// no inference, fully supplied
f16<A, B, D>();
f16<A, B, D>(a);
f16<A, B, D>(a, b);
f16<A, B, D>(a, b, d);
// function with a type parameter with a default that refers to a later type parameter with a default that refers to an earlier type parameter in a union
declare function f17<T = U, U = T | B>(a?: T, b?: U): [T, U];
// inference
f17();
f17(a);
f17(a, a);
f17(a, b);
f17(a, c);
// no inference, partially supplied
f17<A>();
f17<A>(a);
f17<A>(a, a);
f17<A>(a, b);
// no inference, fully supplied
f17<A, C>();
f17<A, C>(a);
f17<A, C>(a, c);
// function with a type parameter without a default and a type parameter with a default that refers to a later type parameter with a default that refers to an earlier type parameter in a union
declare function f18<T, U = V, V = U | C>(a?: T, b?: U, c?: V): [T, U, V];
// inference
f18();
f18(a);
f18(a, b);
f18(a, b, b);
f18(a, b, c);
// no inference, partially supplied
f18<A>();
f18<A>(a);
f18<A>(a, b);
f18<A>(a, b, b);
f18<A>(a, b, c);
f18<A, B>();
f18<A, B>(a);
f18<A, B>(a, b);
f18<A, B>(a, b, b);
f18<A, B>(a, b, c);
// no inference, fully supplied
f18<A, B, D>();
f18<A, B, D>(a);
f18<A, B, D>(a, b);
f18<A, B, D>(a, b, d);
// function with a type parameter with a default that refers to a later type parameter with a default that refers to an earlier type parameter in an intersection
declare function f19<T = U, U = T & B>(a?: T, b?: U): [T, U];
// inference
f19();
f19(a);
f19(a, a);
f19(a, b);
f19(a, ab);
f19(a, c);
// no inference, partially supplied
f19<A>();
f19<A>(a);
f19<A>(a, ab);
// no inference, fully supplied
f19<A, C>();
f19<A, C>(a);
f19<A, C>(a, c);
// function with a type parameter without a default and a type parameter with a default that refers to a later type parameter with a default that refers to an earlier type parameter in an intersection
declare function f20<T, U = V, V = U & C>(a?: T, b?: U, c?: V): [T, U, V];
// inference
f20();
f20(a);
f20(a, b);
f20(a, b, c);
// no inference, partially supplied
f20<A>();
f20<A>(a);
f20<A>(a, b);
f20<A>(a, b, bc);
f20<A, B>();
f20<A, B>(a);
f20<A, B>(a, b);
f20<A, B>(a, b, bc);
// no inference, fully supplied
f20<A, B, D>();
f20<A, B, D>(a);
f20<A, B, D>(a, b);
f20<A, B, D>(a, b, d);
interface i00<T = number> { a: T; }
const i00c00 = (<i00>x).a;
@@ -91,6 +421,15 @@ interface i04<T> {}
interface i04<T = number> {}
interface i04<T = number, U = string> {}
interface i05<T = T> { a: T; }
const i05c00 = (<i05>x).a;
const i05c01 = (<i05<number>>x).a;
interface i06<T = U, U = T> { a: [T, U]; }
const i06c00 = (<i06>x).a;
const i06c01 = (<i06<number>>x).a;
const i06c02 = (<i06<number, string>>x).a;
interface Base01<T> { a: T; }
interface Base01Constructor { new <T = number>(a?: T): Base01<T>; }
+5 -14
View File
@@ -2,17 +2,10 @@
declare const x: any;
declare function f00<T = T>(): void;
declare function f01<T = U, U = T>(): void;
declare function f02<T = U, U>();
declare function f03<T extends string = number>(): void;
declare function f04<T extends string, U extends number = T>(): void;
declare function f05<T, U extends number = T>(): void;
declare function f06<T, U extends T = number>(): void;
declare function f07<T = U, U = T | { a: number }>(): void;
declare function f08<T = U, U = T & { a: number }>(): void;
declare function f09<T = U, U = T | { a: number }>(): void;
declare function f10<T = U, U = T & { a: number }>(): void;
declare function f03<T extends string = number>(): void; // error
declare function f04<T extends string, U extends number = T>(): void; // error
declare function f05<T, U extends number = T>(): void; // error
declare function f06<T, U extends T = number>(): void; // error
declare function f11<T, U, V = number>(): void;
f11(); // ok
@@ -31,9 +24,7 @@ interface i00<U = number> { } // error
interface i01<T = number> { } // ok
interface i01<T = string> { } // error
interface i02<T = T> { } // error
interface i03<T = U, U = T> { } // error
interface i04<T = U, U> { } // error
interface i04<T = number, U> { } // error
interface i05<T extends string = number> { } // error
interface i06<T extends string, U extends number = T> { } // error
interface i07<T, U extends number = T> { } // error