mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-01 03:50:58 -06:00
Merge pull request #29179 from Microsoft/typeParameterDefaultForwardReference
No self or forward references in type parameter defaults
This commit is contained in:
commit
fd3af78b8b
@ -7928,22 +7928,17 @@ namespace ts {
|
||||
const numTypeArguments = length(typeArguments);
|
||||
if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
|
||||
const result = typeArguments ? typeArguments.slice() : [];
|
||||
|
||||
// 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 forward reference, the empty object type is used.
|
||||
const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
const circularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType));
|
||||
// Map invalid forward references in default types to the error type
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper);
|
||||
result[i] = errorType;
|
||||
}
|
||||
const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
const mapper = createTypeMapper(typeParameters!, result);
|
||||
let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
|
||||
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
|
||||
defaultType = anyType;
|
||||
}
|
||||
result[i] = defaultType ? instantiateType(defaultType, mapper) : baseDefaultType;
|
||||
result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters!, result)) : baseDefaultType;
|
||||
}
|
||||
result.length = typeParameters!.length;
|
||||
return result;
|
||||
@ -26466,6 +26461,7 @@ namespace ts {
|
||||
if (produceDiagnostics) {
|
||||
if (node.default) {
|
||||
seenDefault = true;
|
||||
checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
|
||||
}
|
||||
else if (seenDefault) {
|
||||
error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
|
||||
@ -26480,6 +26476,24 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/** Check that type parameter defaults only reference previously declared type parameters */
|
||||
function checkTypeParametersNotReferenced(root: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>, index: number) {
|
||||
visit(root);
|
||||
function visit(node: Node) {
|
||||
if (node.kind === SyntaxKind.TypeReference) {
|
||||
const type = getTypeFromTypeReference(<TypeReferenceNode>node);
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
for (let i = index; i < typeParameters.length; i++) {
|
||||
if (type.symbol === getSymbolOfNode(typeParameters[i])) {
|
||||
error(node, Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
}
|
||||
|
||||
/** Check that type parameter lists are identical across multiple declarations */
|
||||
function checkTypeParameterListsIdentical(symbol: Symbol) {
|
||||
if (symbol.declarations.length === 1) {
|
||||
|
||||
@ -2537,6 +2537,10 @@
|
||||
"category": "Error",
|
||||
"code": 2743
|
||||
},
|
||||
"Type parameter defaults can only reference previously declared type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2744
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
528
tests/baselines/reference/genericDefaults.errors.txt
Normal file
528
tests/baselines/reference/genericDefaults.errors.txt
Normal file
@ -0,0 +1,528 @@
|
||||
tests/cases/compiler/genericDefaults.ts(44,26): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(237,26): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(254,29): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(277,26): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(292,29): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(314,26): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(332,29): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(357,26): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(375,29): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(423,19): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/genericDefaults.ts(427,19): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
|
||||
|
||||
==== tests/cases/compiler/genericDefaults.ts (11 errors) ====
|
||||
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;
|
||||
|
||||
// function without type parameters
|
||||
declare function f00(a?: A): A;
|
||||
// no inference
|
||||
f00();
|
||||
f00(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);
|
||||
|
||||
// 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);
|
||||
|
||||
// function with a type parameter with a default that refers to itself
|
||||
declare function f03<T = T>(a?: T): T;
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// inference
|
||||
f03();
|
||||
f03(a);
|
||||
f03(b);
|
||||
// no inference, fully supplied
|
||||
f03<A>();
|
||||
f03<A>(a);
|
||||
f03<B>();
|
||||
f03<B>(b);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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];
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
// 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;
|
||||
const i00c01 = (<i00<number>>x).a;
|
||||
|
||||
interface i01<T, U = T> { a: [T, U]; }
|
||||
const i01c00 = (<i01<number>>x).a;
|
||||
const i01c01 = (<i01<number, string>>x).a;
|
||||
|
||||
interface i02<T extends number, U = T> { a: [T, U]; }
|
||||
const i02c00 = (<i02<number>>x).a;
|
||||
const i02c01 = (<i02<1>>x).a;
|
||||
const i02c02 = (<i02<number, number>>x).a;
|
||||
const i02c03 = (<i02<1, number>>x).a;
|
||||
const i02c04 = (<i02<number, 1>>x).a;
|
||||
|
||||
interface i03<T extends number, U extends T = T> { a: [T, U]; }
|
||||
const i03c00 = (<i03<number>>x).a;
|
||||
const i03c01 = (<i03<1>>x).a;
|
||||
const i03c02 = (<i03<number, number>>x).a;
|
||||
const i03c03 = (<i03<1, 1>>x).a;
|
||||
const i03c04 = (<i03<number, 1>>x).a;
|
||||
|
||||
interface i04 {}
|
||||
interface i04<T> {}
|
||||
interface i04<T = number> {}
|
||||
interface i04<T = number, U = string> {}
|
||||
|
||||
interface i05<T = T> { a: T; }
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
const i05c00 = (<i05>x).a;
|
||||
const i05c01 = (<i05<number>>x).a;
|
||||
|
||||
interface i06<T = U, U = T> { a: [T, U]; }
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
const i06c00 = (<i06>x).a;
|
||||
const i06c01 = (<i06<number>>x).a;
|
||||
const i06c02 = (<i06<number, string>>x).a;
|
||||
|
||||
interface i07 { a: A; }
|
||||
interface i07<A = number> { b: A; }
|
||||
const i07c00 = (<i07>x).a;
|
||||
const i07c01 = (<i07>x).b;
|
||||
const i07c02 = (<i07<B>>x).a;
|
||||
const i07c03 = (<i07<B>>x).b;
|
||||
|
||||
interface Base01<T> { a: T; }
|
||||
interface Base01Constructor { new <T = number>(a?: T): Base01<T>; }
|
||||
|
||||
declare const Base01: Base01Constructor;
|
||||
const Base01c00 = new Base01();
|
||||
const Base01c01 = new Base01(1);
|
||||
const Base01c02 = new Base01<number>();
|
||||
const Base01c03 = new Base01<number>(1);
|
||||
|
||||
declare class Derived01<T> extends Base01<T> { }
|
||||
const Derived01c00 = new Derived01();
|
||||
const Derived01c01 = new Derived01(1);
|
||||
const Derived01c02 = new Derived01<number>();
|
||||
const Derived01c03 = new Derived01<number>(1);
|
||||
|
||||
declare class Derived02<T = string> extends Base01<T> { }
|
||||
const Derived02c00 = new Derived02();
|
||||
const Derived02c01 = new Derived02(1);
|
||||
const Derived02c02 = new Derived02<number>();
|
||||
const Derived02c03 = new Derived02<number>(1);
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/16211
|
||||
interface Base02 {}
|
||||
interface Base02Constructor { new <T = A>(a: T): Base02 & T; }
|
||||
declare const Base02: Base02Constructor;
|
||||
declare class Derived03 extends Base02 {}
|
||||
const Derived03c00 = new Derived03(ab);
|
||||
const Derived03c01 = Derived03c00.a;
|
||||
type DerivedProps = keyof Derived03;
|
||||
|
||||
type t00<T = number> = { a: T; }
|
||||
const t00c00 = (<t00>x).a;
|
||||
const t00c01 = (<t00<number>>x).a;
|
||||
|
||||
type t01<T, U = T> = { a: [T, U]; }
|
||||
const t01c00 = (<t01<number>>x).a;
|
||||
const t01c01 = (<t01<number, string>>x).a;
|
||||
|
||||
type t02<T extends number, U = T> = { a: [T, U]; }
|
||||
const t02c00 = (<t02<number>>x).a;
|
||||
const t02c01 = (<t02<1>>x).a;
|
||||
const t02c02 = (<t02<number, number>>x).a;
|
||||
const t02c03 = (<t02<1, number>>x).a;
|
||||
const t02c04 = (<t02<number, 1>>x).a;
|
||||
|
||||
type t03<T extends number, U extends T = T> = { a: [T, U]; }
|
||||
const t03c00 = (<t03<number>>x).a;
|
||||
const t03c01 = (<t03<1>>x).a;
|
||||
const t03c02 = (<t03<number, number>>x).a;
|
||||
const t03c03 = (<t03<1, 1>>x).a;
|
||||
const t03c04 = (<t03<number, 1>>x).a;
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/16221
|
||||
interface SelfReference<T = SelfReference<string>> {}
|
||||
@ -949,12 +949,12 @@ interface i04<T = number, U = string> {
|
||||
interface i05<T = T> {
|
||||
a: T;
|
||||
}
|
||||
declare const i05c00: {};
|
||||
declare const i05c00: any;
|
||||
declare const i05c01: number;
|
||||
interface i06<T = U, U = T> {
|
||||
a: [T, U];
|
||||
}
|
||||
declare const i06c00: [{}, {}];
|
||||
declare const i06c00: [any, any];
|
||||
declare const i06c01: [number, number];
|
||||
declare const i06c02: [number, string];
|
||||
interface i07 {
|
||||
|
||||
@ -1015,22 +1015,22 @@ f14(a, b, d);
|
||||
|
||||
// no inference, partially supplied
|
||||
f14<A>();
|
||||
>f14<A>() : [A, {}, C]
|
||||
>f14<A>() : [A, any, C]
|
||||
>f14 : <T, U = V, V = C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
|
||||
f14<A>(a);
|
||||
>f14<A>(a) : [A, {}, C]
|
||||
>f14<A>(a) : [A, any, C]
|
||||
>f14 : <T, U = V, V = C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
|
||||
f14<A>(a, b);
|
||||
>f14<A>(a, b) : [A, {}, C]
|
||||
>f14<A>(a, b) : [A, any, C]
|
||||
>f14 : <T, U = V, V = C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
f14<A>(a, b, c);
|
||||
>f14<A>(a, b, c) : [A, {}, C]
|
||||
>f14<A>(a, b, c) : [A, any, C]
|
||||
>f14 : <T, U = V, V = C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
@ -1167,22 +1167,22 @@ f16(a, b, b);
|
||||
|
||||
// no inference, partially supplied
|
||||
f16<A>();
|
||||
>f16<A>() : [A, {}, {}]
|
||||
>f16<A>() : [A, any, any]
|
||||
>f16 : <T, U = V, V = U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
|
||||
f16<A>(a);
|
||||
>f16<A>(a) : [A, {}, {}]
|
||||
>f16<A>(a) : [A, any, any]
|
||||
>f16 : <T, U = V, V = U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
|
||||
f16<A>(a, b);
|
||||
>f16<A>(a, b) : [A, {}, {}]
|
||||
>f16<A>(a, b) : [A, any, any]
|
||||
>f16 : <T, U = V, V = U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
f16<A>(a, b, b);
|
||||
>f16<A>(a, b, b) : [A, {}, {}]
|
||||
>f16<A>(a, b, b) : [A, any, any]
|
||||
>f16 : <T, U = V, V = U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
@ -1344,29 +1344,29 @@ f18(a, b, c);
|
||||
|
||||
// no inference, partially supplied
|
||||
f18<A>();
|
||||
>f18<A>() : [A, {}, {} | C]
|
||||
>f18<A>() : [A, any, any]
|
||||
>f18 : <T, U = V, V = C | U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
|
||||
f18<A>(a);
|
||||
>f18<A>(a) : [A, {}, {} | C]
|
||||
>f18<A>(a) : [A, any, any]
|
||||
>f18 : <T, U = V, V = C | U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
|
||||
f18<A>(a, b);
|
||||
>f18<A>(a, b) : [A, {}, {} | C]
|
||||
>f18<A>(a, b) : [A, any, any]
|
||||
>f18 : <T, U = V, V = C | U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
f18<A>(a, b, b);
|
||||
>f18<A>(a, b, b) : [A, {}, {} | C]
|
||||
>f18<A>(a, b, b) : [A, any, any]
|
||||
>f18 : <T, U = V, V = C | U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
>b : B
|
||||
|
||||
f18<A>(a, b, c);
|
||||
>f18<A>(a, b, c) : [A, {}, {} | C]
|
||||
>f18<A>(a, b, c) : [A, any, any]
|
||||
>f18 : <T, U = V, V = C | U>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
@ -1528,22 +1528,22 @@ f20(a, b, c);
|
||||
|
||||
// no inference, partially supplied
|
||||
f20<A>();
|
||||
>f20<A>() : [A, {}, C]
|
||||
>f20<A>() : [A, any, any]
|
||||
>f20 : <T, U = V, V = U & C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
|
||||
f20<A>(a);
|
||||
>f20<A>(a) : [A, {}, C]
|
||||
>f20<A>(a) : [A, any, any]
|
||||
>f20 : <T, U = V, V = U & C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
|
||||
f20<A>(a, b);
|
||||
>f20<A>(a, b) : [A, {}, C]
|
||||
>f20<A>(a, b) : [A, any, any]
|
||||
>f20 : <T, U = V, V = U & C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
f20<A>(a, b, bc);
|
||||
>f20<A>(a, b, bc) : [A, {}, C]
|
||||
>f20<A>(a, b, bc) : [A, any, any]
|
||||
>f20 : <T, U = V, V = U & C>(a?: T, b?: U, c?: V) => [T, U, V]
|
||||
>a : A
|
||||
>b : B
|
||||
@ -1727,12 +1727,12 @@ interface i05<T = T> { a: T; }
|
||||
>a : T
|
||||
|
||||
const i05c00 = (<i05>x).a;
|
||||
>i05c00 : {}
|
||||
>(<i05>x).a : {}
|
||||
>(<i05>x) : i05<{}>
|
||||
><i05>x : i05<{}>
|
||||
>i05c00 : any
|
||||
>(<i05>x).a : any
|
||||
>(<i05>x) : i05<any>
|
||||
><i05>x : i05<any>
|
||||
>x : any
|
||||
>a : {}
|
||||
>a : any
|
||||
|
||||
const i05c01 = (<i05<number>>x).a;
|
||||
>i05c01 : number
|
||||
@ -1746,12 +1746,12 @@ interface i06<T = U, U = T> { a: [T, U]; }
|
||||
>a : [T, U]
|
||||
|
||||
const i06c00 = (<i06>x).a;
|
||||
>i06c00 : [{}, {}]
|
||||
>(<i06>x).a : [{}, {}]
|
||||
>(<i06>x) : i06<{}, {}>
|
||||
><i06>x : i06<{}, {}>
|
||||
>i06c00 : [any, any]
|
||||
>(<i06>x).a : [any, any]
|
||||
>(<i06>x) : i06<any, any>
|
||||
><i06>x : i06<any, any>
|
||||
>x : any
|
||||
>a : [{}, {}]
|
||||
>a : [any, any]
|
||||
|
||||
const i06c01 = (<i06<number>>x).a;
|
||||
>i06c01 : [number, number]
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
tests/cases/compiler/tile1.ts(6,81): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
|
||||
|
||||
==== tests/cases/compiler/tile1.ts (1 errors) ====
|
||||
interface Lifecycle<Attrs, State> {
|
||||
oninit?(vnode: Vnode<Attrs, State>): number;
|
||||
[_: number]: any;
|
||||
}
|
||||
|
||||
interface Vnode<Attrs, State extends Lifecycle<Attrs, State> = Lifecycle<Attrs, State>> {
|
||||
~~~~~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tag: Component<Attrs, State>;
|
||||
}
|
||||
|
||||
interface Component<Attrs, State> {
|
||||
view(this: State, vnode: Vnode<Attrs, State>): number;
|
||||
}
|
||||
|
||||
interface ClassComponent<A> extends Lifecycle<A, ClassComponent<A>> {
|
||||
oninit?(vnode: Vnode<A, this>): number;
|
||||
view(vnode: Vnode<A, this>): number;
|
||||
}
|
||||
|
||||
interface MyAttrs { id: number }
|
||||
class C implements ClassComponent<MyAttrs> {
|
||||
view(v: Vnode<MyAttrs>) { return 0; }
|
||||
}
|
||||
|
||||
const test8: ClassComponent<any> = new C();
|
||||
==== tests/cases/compiler/file1.js (0 errors) ====
|
||||
/** @type {ClassComponent<any>} */
|
||||
const test9 = new C();
|
||||
|
||||
@ -37,8 +37,8 @@ class C implements ClassComponent<MyAttrs> {
|
||||
>C : C
|
||||
|
||||
view(v: Vnode<MyAttrs>) { return 0; }
|
||||
>view : (v: Vnode<MyAttrs, Lifecycle<MyAttrs, Lifecycle<{}, {}>>>) => number
|
||||
>v : Vnode<MyAttrs, Lifecycle<MyAttrs, Lifecycle<{}, {}>>>
|
||||
>view : (v: Vnode<MyAttrs, Lifecycle<MyAttrs, any>>) => number
|
||||
>v : Vnode<MyAttrs, Lifecycle<MyAttrs, any>>
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(3,18): error TS2322: Type '{ foo: string; }' is not assignable to type 'Test<string>'.
|
||||
Object literal may only specify known properties, and 'foo' does not exist in type 'Test<string>'.
|
||||
tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(5,19): error TS2322: Type '{}' is not assignable to type 'string'.
|
||||
tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(1,30): error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(3,18): error TS2322: Type '{ foo: string; }' is not assignable to type 'Test<any>'.
|
||||
Object literal may only specify known properties, and 'foo' does not exist in type 'Test<any>'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts (2 errors) ====
|
||||
type Test<T extends string = T> = { value: T };
|
||||
type Test<T extends string = T> = { value: T }; // Error
|
||||
~
|
||||
!!! error TS2744: Type parameter defaults can only reference previously declared type parameters.
|
||||
|
||||
let zz: Test = { foo: "abc" }; // should error on comparison with Test<string>
|
||||
~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Test<string>'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'foo' does not exist in type 'Test<string>'.
|
||||
!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Test<any>'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'foo' does not exist in type 'Test<any>'.
|
||||
|
||||
let zzy: Test = { value: {} }; // should error
|
||||
~~~~~
|
||||
!!! error TS2322: Type '{}' is not assignable to type 'string'.
|
||||
!!! related TS6500 tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts:1:37: The expected type comes from property 'value' which is declared here on type 'Test<string>'
|
||||
let zzy: Test = { value: {} };
|
||||
|
||||
// Simplified repro from #28873
|
||||
|
||||
class C1<T extends C1 = any> {}
|
||||
|
||||
class C2<T extends C2<any> = any> {}
|
||||
|
||||
@ -1,11 +1,28 @@
|
||||
//// [typeArgumentDefaultUsesConstraintOnCircularDefault.ts]
|
||||
type Test<T extends string = T> = { value: T };
|
||||
type Test<T extends string = T> = { value: T }; // Error
|
||||
|
||||
let zz: Test = { foo: "abc" }; // should error on comparison with Test<string>
|
||||
|
||||
let zzy: Test = { value: {} }; // should error
|
||||
let zzy: Test = { value: {} };
|
||||
|
||||
// Simplified repro from #28873
|
||||
|
||||
class C1<T extends C1 = any> {}
|
||||
|
||||
class C2<T extends C2<any> = any> {}
|
||||
|
||||
|
||||
//// [typeArgumentDefaultUsesConstraintOnCircularDefault.js]
|
||||
var zz = { foo: "abc" }; // should error on comparison with Test<string>
|
||||
var zzy = { value: {} }; // should error
|
||||
var zzy = { value: {} };
|
||||
// Simplified repro from #28873
|
||||
var C1 = /** @class */ (function () {
|
||||
function C1() {
|
||||
}
|
||||
return C1;
|
||||
}());
|
||||
var C2 = /** @class */ (function () {
|
||||
function C2() {
|
||||
}
|
||||
return C2;
|
||||
}());
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
=== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts ===
|
||||
type Test<T extends string = T> = { value: T };
|
||||
type Test<T extends string = T> = { value: T }; // Error
|
||||
>Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 10))
|
||||
>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 10))
|
||||
@ -11,8 +11,20 @@ let zz: Test = { foo: "abc" }; // should error on comparison with Test<string>
|
||||
>Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 2, 16))
|
||||
|
||||
let zzy: Test = { value: {} }; // should error
|
||||
let zzy: Test = { value: {} };
|
||||
>zzy : Symbol(zzy, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 3))
|
||||
>Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0))
|
||||
>value : Symbol(value, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 17))
|
||||
|
||||
// Simplified repro from #28873
|
||||
|
||||
class C1<T extends C1 = any> {}
|
||||
>C1 : Symbol(C1, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 30))
|
||||
>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 8, 9))
|
||||
>C1 : Symbol(C1, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 30))
|
||||
|
||||
class C2<T extends C2<any> = any> {}
|
||||
>C2 : Symbol(C2, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 8, 31))
|
||||
>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 10, 9))
|
||||
>C2 : Symbol(C2, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 8, 31))
|
||||
|
||||
|
||||
@ -1,17 +1,25 @@
|
||||
=== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts ===
|
||||
type Test<T extends string = T> = { value: T };
|
||||
type Test<T extends string = T> = { value: T }; // Error
|
||||
>Test : Test<T>
|
||||
>value : T
|
||||
|
||||
let zz: Test = { foo: "abc" }; // should error on comparison with Test<string>
|
||||
>zz : Test<string>
|
||||
>zz : Test<any>
|
||||
>{ foo: "abc" } : { foo: string; }
|
||||
>foo : string
|
||||
>"abc" : "abc"
|
||||
|
||||
let zzy: Test = { value: {} }; // should error
|
||||
>zzy : Test<string>
|
||||
let zzy: Test = { value: {} };
|
||||
>zzy : Test<any>
|
||||
>{ value: {} } : { value: {}; }
|
||||
>value : {}
|
||||
>{} : {}
|
||||
|
||||
// Simplified repro from #28873
|
||||
|
||||
class C1<T extends C1 = any> {}
|
||||
>C1 : C1<T>
|
||||
|
||||
class C2<T extends C2<any> = any> {}
|
||||
>C2 : C2<T>
|
||||
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
type Test<T extends string = T> = { value: T };
|
||||
type Test<T extends string = T> = { value: T }; // Error
|
||||
|
||||
let zz: Test = { foo: "abc" }; // should error on comparison with Test<string>
|
||||
|
||||
let zzy: Test = { value: {} }; // should error
|
||||
let zzy: Test = { value: {} };
|
||||
|
||||
// Simplified repro from #28873
|
||||
|
||||
class C1<T extends C1 = any> {}
|
||||
|
||||
class C2<T extends C2<any> = any> {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user