diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 23c5568f2e5f4..c63a5dce46f80 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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; @@ -26465,6 +26460,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); @@ -26479,6 +26475,24 @@ namespace ts { } } + /** Check that type parameter defaults only reference previously declared type parameters */ + function checkTypeParametersNotReferenced(root: TypeNode, typeParameters: ReadonlyArray, index: number) { + visit(root); + function visit(node: Node) { + if (node.kind === SyntaxKind.TypeReference) { + const type = getTypeFromTypeReference(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) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b0dfb85ce6d25..57f4c4c561117 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -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", diff --git a/tests/baselines/reference/genericDefaults.errors.txt b/tests/baselines/reference/genericDefaults.errors.txt new file mode 100644 index 0000000000000..0c7d9ccb21d63 --- /dev/null +++ b/tests/baselines/reference/genericDefaults.errors.txt @@ -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(a?: T): T; + // inference + f01(); + f01(a); + // no inference, fully supplied + f01(); + f01(a); + + // function with a type paramter with a default + declare function f02(a?: T): T; + // inference + f02(); + f02(a); + f02(b); + // no inference, fully supplied + f02(); + f02(a); + f02(); + f02(b); + + // function with a type parameter with a default that refers to itself + declare function f03(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(); + f03(a); + f03(); + f03(b); + + // function with a type paramter without a default and a type parameter with a default + declare function f04(a?: T, b?: U): [T, U]; + // inference + f04(); + f04(a); + f04(a, b); + f04(a, c); + // no inference, partially supplied + f04(); + f04(a); + f04(a, b); + // no inference, fully supplied + f04(); + f04(a); + f04(a, b); + f04(); + f04(a); + f04(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(a?: T, b?: U): [T, U]; + // inference + f05(); + f05(a); + f05(a, a); + f05(a, b); + // no inference, partially supplied + f05(); + f05(a); + f05(a, a); + // no inference, fully supplied + f05(); + f05(a); + f05(a, b); + + // function with a type parameter with a default that refers to an earlier type parameter with a default + declare function f06(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(); + f06(a); + f06(a, a); + f06(); + f06(b); + f06(b, b); + // no inference, fully supplied + f06(); + f06(a); + f06(a, b); + f06(); + f06(b); + f06(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(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(); + f07(a); + f07(a, b); + f07(a, b, b); + f07(); + f07(a); + f07(a, b); + f07(a, b, b); + f07(); + f07(a); + f07(a, c); + f07(a, c, c); + // no inference, fully supplied + f07(); + f07(a); + f07(a, b); + f07(a, b, c); + f07(); + f07(a); + f07(a, c); + f07(a, c, d); + + // function with a type parameter with a default that refers to an earlier type parameter with a constraint + declare function f08(a?: T, b?: U): [T, U]; + // inference + f08(); + f08(a); + f08(a, a); + f08(a, b); + // no inference, partially supplied + f08(); + f08(a); + f08(a, a); + // no inference, fully supplied + f08(); + f08(a); + f08(a, b); + + // function with a type parameter with a constraint and a default that refers to an earlier type parameter + declare function f09(a?: T, b?: U): [T, U]; + // inference + f09(); + f09(a); + f09(a, a); + f09(a, ab); + // no inference, partially supplied + f09(); + f09(a); + f09(a, a); + f09(a, ab); + // no inference, fully supplied + f09(); + f09(a); + f09(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(a?: T, b?: U): [T, U]; + // inference + f10(); + f10(a); + f10(a, a); + f10(a, ab); + // no inference, partially supplied + f10(); + f10(a); + f10(a, a); + f10(a, ab); + // no inference, fully supplied + f10(); + f10(a); + f10(a, a); + f10(a, ab); + f10(); + f10(a); + f10(a, ab); + + // function with a type parameter with a default that refers to an earier type parameter in a union + declare function f11(a?: T, b?: U): [T, U]; + // inference + f11(); + f11(a); + f11(a, a); + f11(a, b); + f11(a, c); + // no inference, partially supplied + f11(); + f11(a); + f11(a, a); + f11(a, b); + // no inference, fully supplied + f11(); + f11(a); + f11(a, c); + + // function with a type parameter with a default that refers to an earlier type parameter in an intersection + declare function f12(a?: T, b?: U): [T, U]; + // inference + f12(); + f12(a); + f12(a, a); + f12(a, b); + f12(a, c); + // no inference, partially supplied + f12(); + f12(a); + f12(a, ab); + // no inference, fully supplied + f12(); + f12(a); + f12(a, c); + + // function with a type parameter with a default that refers to a later type parameter with a default + declare function f13(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(); + f13(a); + f13(a, b); + // no inference, fully supplied + f13(); + f13(a); + f13(a, c); + f13(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(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(); + f14(a); + f14(a, b); + f14(a, b, c); + f14(); + f14(a); + f14(a, b); + f14(a, b, c); + // no inference fully supplied + f14(); + f14(a); + f14(a, b); + f14(a, b, d); + + // function with two type parameters with defaults that mutually refer to each other + declare function f15(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(); + f15(a); + f15(a, a); + // no inference, fully supplied + f15(); + f15(a); + f15(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(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(); + f16(a); + f16(a, b); + f16(a, b, b); + f16(); + f16(a); + f16(a, b); + f16(a, b, b); + // no inference, fully supplied + f16(); + f16(a); + f16(a, b); + f16(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(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(); + f17(a); + f17(a, a); + f17(a, b); + // no inference, fully supplied + f17(); + f17(a); + f17(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(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(); + f18(a); + f18(a, b); + f18(a, b, b); + f18(a, b, c); + f18(); + f18(a); + f18(a, b); + f18(a, b, b); + f18(a, b, c); + // no inference, fully supplied + f18(); + f18(a); + f18(a, b); + f18(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(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(); + f19(a); + f19(a, ab); + // no inference, fully supplied + f19(); + f19(a); + f19(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(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(); + f20(a); + f20(a, b); + f20(a, b, bc); + f20(); + f20(a); + f20(a, b); + f20(a, b, bc); + // no inference, fully supplied + f20(); + f20(a); + f20(a, b); + f20(a, b, d); + + interface i00 { a: T; } + const i00c00 = (x).a; + const i00c01 = (>x).a; + + interface i01 { a: [T, U]; } + const i01c00 = (>x).a; + const i01c01 = (>x).a; + + interface i02 { a: [T, U]; } + const i02c00 = (>x).a; + const i02c01 = (>x).a; + const i02c02 = (>x).a; + const i02c03 = (>x).a; + const i02c04 = (>x).a; + + interface i03 { a: [T, U]; } + const i03c00 = (>x).a; + const i03c01 = (>x).a; + const i03c02 = (>x).a; + const i03c03 = (>x).a; + const i03c04 = (>x).a; + + interface i04 {} + interface i04 {} + interface i04 {} + interface i04 {} + + interface i05 { a: T; } + ~ +!!! error TS2744: Type parameter defaults can only reference previously declared type parameters. + const i05c00 = (x).a; + const i05c01 = (>x).a; + + interface i06 { a: [T, U]; } + ~ +!!! error TS2744: Type parameter defaults can only reference previously declared type parameters. + const i06c00 = (x).a; + const i06c01 = (>x).a; + const i06c02 = (>x).a; + + interface i07 { a: A; } + interface i07 { b: A; } + const i07c00 = (x).a; + const i07c01 = (x).b; + const i07c02 = (>x).a; + const i07c03 = (>x).b; + + interface Base01 { a: T; } + interface Base01Constructor { new (a?: T): Base01; } + + declare const Base01: Base01Constructor; + const Base01c00 = new Base01(); + const Base01c01 = new Base01(1); + const Base01c02 = new Base01(); + const Base01c03 = new Base01(1); + + declare class Derived01 extends Base01 { } + const Derived01c00 = new Derived01(); + const Derived01c01 = new Derived01(1); + const Derived01c02 = new Derived01(); + const Derived01c03 = new Derived01(1); + + declare class Derived02 extends Base01 { } + const Derived02c00 = new Derived02(); + const Derived02c01 = new Derived02(1); + const Derived02c02 = new Derived02(); + const Derived02c03 = new Derived02(1); + + // https://github.com/Microsoft/TypeScript/issues/16211 + interface Base02 {} + interface Base02Constructor { new (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 = { a: T; } + const t00c00 = (x).a; + const t00c01 = (>x).a; + + type t01 = { a: [T, U]; } + const t01c00 = (>x).a; + const t01c01 = (>x).a; + + type t02 = { a: [T, U]; } + const t02c00 = (>x).a; + const t02c01 = (>x).a; + const t02c02 = (>x).a; + const t02c03 = (>x).a; + const t02c04 = (>x).a; + + type t03 = { a: [T, U]; } + const t03c00 = (>x).a; + const t03c01 = (>x).a; + const t03c02 = (>x).a; + const t03c03 = (>x).a; + const t03c04 = (>x).a; + + // https://github.com/Microsoft/TypeScript/issues/16221 + interface SelfReference> {} \ No newline at end of file diff --git a/tests/baselines/reference/genericDefaults.js b/tests/baselines/reference/genericDefaults.js index be6b76ea43cdb..4cd1127724f11 100644 --- a/tests/baselines/reference/genericDefaults.js +++ b/tests/baselines/reference/genericDefaults.js @@ -949,12 +949,12 @@ interface i04 { interface i05 { a: T; } -declare const i05c00: {}; +declare const i05c00: any; declare const i05c01: number; interface i06 { a: [T, U]; } -declare const i06c00: [{}, {}]; +declare const i06c00: [any, any]; declare const i06c01: [number, number]; declare const i06c02: [number, string]; interface i07 { diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types index 839994cc96532..c439d96a08b44 100644 --- a/tests/baselines/reference/genericDefaults.types +++ b/tests/baselines/reference/genericDefaults.types @@ -1015,22 +1015,22 @@ f14(a, b, d); // no inference, partially supplied f14(); ->f14() : [A, {}, C] +>f14() : [A, any, C] >f14 : (a?: T, b?: U, c?: V) => [T, U, V] f14(a); ->f14(a) : [A, {}, C] +>f14(a) : [A, any, C] >f14 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A f14(a, b); ->f14(a, b) : [A, {}, C] +>f14(a, b) : [A, any, C] >f14 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A >b : B f14(a, b, c); ->f14(a, b, c) : [A, {}, C] +>f14(a, b, c) : [A, any, C] >f14 : (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(); ->f16() : [A, {}, {}] +>f16() : [A, any, any] >f16 : (a?: T, b?: U, c?: V) => [T, U, V] f16(a); ->f16(a) : [A, {}, {}] +>f16(a) : [A, any, any] >f16 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A f16(a, b); ->f16(a, b) : [A, {}, {}] +>f16(a, b) : [A, any, any] >f16 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A >b : B f16(a, b, b); ->f16(a, b, b) : [A, {}, {}] +>f16(a, b, b) : [A, any, any] >f16 : (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(); ->f18() : [A, {}, {} | C] +>f18() : [A, any, any] >f18 : (a?: T, b?: U, c?: V) => [T, U, V] f18(a); ->f18(a) : [A, {}, {} | C] +>f18(a) : [A, any, any] >f18 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A f18(a, b); ->f18(a, b) : [A, {}, {} | C] +>f18(a, b) : [A, any, any] >f18 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A >b : B f18(a, b, b); ->f18(a, b, b) : [A, {}, {} | C] +>f18(a, b, b) : [A, any, any] >f18 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A >b : B >b : B f18(a, b, c); ->f18(a, b, c) : [A, {}, {} | C] +>f18(a, b, c) : [A, any, any] >f18 : (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(); ->f20() : [A, {}, C] +>f20() : [A, any, any] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] f20(a); ->f20(a) : [A, {}, C] +>f20(a) : [A, any, any] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A f20(a, b); ->f20(a, b) : [A, {}, C] +>f20(a, b) : [A, any, any] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A >b : B f20(a, b, bc); ->f20(a, b, bc) : [A, {}, C] +>f20(a, b, bc) : [A, any, any] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A >b : B @@ -1727,12 +1727,12 @@ interface i05 { a: T; } >a : T const i05c00 = (x).a; ->i05c00 : {} ->(x).a : {} ->(x) : i05<{}> ->x : i05<{}> +>i05c00 : any +>(x).a : any +>(x) : i05 +>x : i05 >x : any ->a : {} +>a : any const i05c01 = (>x).a; >i05c01 : number @@ -1746,12 +1746,12 @@ interface i06 { a: [T, U]; } >a : [T, U] const i06c00 = (x).a; ->i06c00 : [{}, {}] ->(x).a : [{}, {}] ->(x) : i06<{}, {}> ->x : i06<{}, {}> +>i06c00 : [any, any] +>(x).a : [any, any] +>(x) : i06 +>x : i06 >x : any ->a : [{}, {}] +>a : [any, any] const i06c01 = (>x).a; >i06c01 : [number, number] diff --git a/tests/baselines/reference/subclassThisTypeAssignable.errors.txt b/tests/baselines/reference/subclassThisTypeAssignable.errors.txt new file mode 100644 index 0000000000000..f1d661695d1e3 --- /dev/null +++ b/tests/baselines/reference/subclassThisTypeAssignable.errors.txt @@ -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 { + oninit?(vnode: Vnode): number; + [_: number]: any; + } + + interface Vnode = Lifecycle> { + ~~~~~ +!!! error TS2744: Type parameter defaults can only reference previously declared type parameters. + tag: Component; + } + + interface Component { + view(this: State, vnode: Vnode): number; + } + + interface ClassComponent extends Lifecycle> { + oninit?(vnode: Vnode): number; + view(vnode: Vnode): number; + } + + interface MyAttrs { id: number } + class C implements ClassComponent { + view(v: Vnode) { return 0; } + } + + const test8: ClassComponent = new C(); +==== tests/cases/compiler/file1.js (0 errors) ==== + /** @type {ClassComponent} */ + const test9 = new C(); + \ No newline at end of file diff --git a/tests/baselines/reference/subclassThisTypeAssignable.types b/tests/baselines/reference/subclassThisTypeAssignable.types index 711b0056277f8..9608613f1ffb1 100644 --- a/tests/baselines/reference/subclassThisTypeAssignable.types +++ b/tests/baselines/reference/subclassThisTypeAssignable.types @@ -37,8 +37,8 @@ class C implements ClassComponent { >C : C view(v: Vnode) { return 0; } ->view : (v: Vnode>>) => number ->v : Vnode>> +>view : (v: Vnode>) => number +>v : Vnode> >0 : 0 } diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt index 71e3ef046277a..756c1f9da3eba 100644 --- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt @@ -1,18 +1,23 @@ -tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(3,18): error TS2322: Type '{ foo: string; }' is not assignable to type 'Test'. - Object literal may only specify known properties, and 'foo' does not exist in type 'Test'. -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'. + Object literal may only specify known properties, and 'foo' does not exist in type 'Test'. ==== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts (2 errors) ==== - type Test = { value: T }; + type Test = { 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 ~~~~~~~~~~ -!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Test'. -!!! error TS2322: Object literal may only specify known properties, and 'foo' does not exist in type 'Test'. +!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Test'. +!!! error TS2322: Object literal may only specify known properties, and 'foo' does not exist in type 'Test'. - 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' + let zzy: Test = { value: {} }; + + // Simplified repro from #28873 + + class C1 {} + + class C2 = any> {} \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js index 296a0063fe270..a50e7cab397b4 100644 --- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js @@ -1,11 +1,28 @@ //// [typeArgumentDefaultUsesConstraintOnCircularDefault.ts] -type Test = { value: T }; +type Test = { value: T }; // Error let zz: Test = { foo: "abc" }; // should error on comparison with Test -let zzy: Test = { value: {} }; // should error +let zzy: Test = { value: {} }; + +// Simplified repro from #28873 + +class C1 {} + +class C2 = any> {} //// [typeArgumentDefaultUsesConstraintOnCircularDefault.js] var zz = { foo: "abc" }; // should error on comparison with Test -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; +}()); diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols index 2181e34188964..4c227899de9f1 100644 --- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts === -type Test = { value: T }; +type Test = { 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 >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 {} +>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 = 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)) + diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types index 7c0d469da4619..91078dad88432 100644 --- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types @@ -1,17 +1,25 @@ === tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts === -type Test = { value: T }; +type Test = { value: T }; // Error >Test : Test >value : T let zz: Test = { foo: "abc" }; // should error on comparison with Test ->zz : Test +>zz : Test >{ foo: "abc" } : { foo: string; } >foo : string >"abc" : "abc" -let zzy: Test = { value: {} }; // should error ->zzy : Test +let zzy: Test = { value: {} }; +>zzy : Test >{ value: {} } : { value: {}; } >value : {} >{} : {} +// Simplified repro from #28873 + +class C1 {} +>C1 : C1 + +class C2 = any> {} +>C2 : C2 + diff --git a/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts b/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts index b8361ea571496..ca5a270f6e78a 100644 --- a/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts +++ b/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts @@ -1,5 +1,11 @@ -type Test = { value: T }; +type Test = { value: T }; // Error let zz: Test = { foo: "abc" }; // should error on comparison with Test -let zzy: Test = { value: {} }; // should error +let zzy: Test = { value: {} }; + +// Simplified repro from #28873 + +class C1 {} + +class C2 = any> {}