From 1191e2e7319ee2ac33a5e2d367388862eb10c673 Mon Sep 17 00:00:00 2001 From: Tiago Tristao Date: Mon, 5 Oct 2020 21:21:38 +0100 Subject: [PATCH] Fix class expression from being assignable if types don't match (#40660) * Fix class expression from being assignable if types don't match * Fix class expression from being assignable if types don't match --- src/compiler/checker.ts | 2 +- .../classExpressionAssignment.errors.txt | 16 ++++++++++++++++ .../reference/classExpressionAssignment.js | 16 ++++++++++++++++ .../reference/classExpressionAssignment.symbols | 13 +++++++++++++ .../reference/classExpressionAssignment.types | 11 +++++++++++ .../cases/compiler/classExpressionAssignment.ts | 6 ++++++ 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/classExpressionAssignment.errors.txt create mode 100644 tests/baselines/reference/classExpressionAssignment.js create mode 100644 tests/baselines/reference/classExpressionAssignment.symbols create mode 100644 tests/baselines/reference/classExpressionAssignment.types create mode 100644 tests/cases/compiler/classExpressionAssignment.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb1e2bf2f5c..8d4bec287a9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28180,7 +28180,7 @@ namespace ts { let name: Expression | BindingName | undefined; let decl: Node | undefined; if (isVariableDeclaration(node.parent) && node.parent.initializer === node) { - if (!isInJSFile(node) && !isVarConst(node.parent)) { + if (!isInJSFile(node) && !(isVarConst(node.parent) && isFunctionLikeDeclaration(node))) { return undefined; } name = node.parent.name; diff --git a/tests/baselines/reference/classExpressionAssignment.errors.txt b/tests/baselines/reference/classExpressionAssignment.errors.txt new file mode 100644 index 00000000000..2519e23b441 --- /dev/null +++ b/tests/baselines/reference/classExpressionAssignment.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/classExpressionAssignment.ts(6,7): error TS2322: Type 'typeof A' is not assignable to type 'new () => A'. + Property 'prop' is missing in type 'A' but required in type 'A'. + + +==== tests/cases/compiler/classExpressionAssignment.ts (1 errors) ==== + interface A { + prop: string; + } + + // This is invalid + const A: {new(): A} = class {} + ~ +!!! error TS2322: Type 'typeof A' is not assignable to type 'new () => A'. +!!! error TS2322: Property 'prop' is missing in type 'A' but required in type 'A'. +!!! related TS2728 tests/cases/compiler/classExpressionAssignment.ts:2:3: 'prop' is declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionAssignment.js b/tests/baselines/reference/classExpressionAssignment.js new file mode 100644 index 00000000000..8d924cfc44c --- /dev/null +++ b/tests/baselines/reference/classExpressionAssignment.js @@ -0,0 +1,16 @@ +//// [classExpressionAssignment.ts] +interface A { + prop: string; +} + +// This is invalid +const A: {new(): A} = class {} + + +//// [classExpressionAssignment.js] +// This is invalid +var A = /** @class */ (function () { + function A() { + } + return A; +}()); diff --git a/tests/baselines/reference/classExpressionAssignment.symbols b/tests/baselines/reference/classExpressionAssignment.symbols new file mode 100644 index 00000000000..a1d8abd41cf --- /dev/null +++ b/tests/baselines/reference/classExpressionAssignment.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/classExpressionAssignment.ts === +interface A { +>A : Symbol(A, Decl(classExpressionAssignment.ts, 0, 0), Decl(classExpressionAssignment.ts, 5, 5)) + + prop: string; +>prop : Symbol(A.prop, Decl(classExpressionAssignment.ts, 0, 13)) +} + +// This is invalid +const A: {new(): A} = class {} +>A : Symbol(A, Decl(classExpressionAssignment.ts, 0, 0), Decl(classExpressionAssignment.ts, 5, 5)) +>A : Symbol(A, Decl(classExpressionAssignment.ts, 0, 0), Decl(classExpressionAssignment.ts, 5, 5)) + diff --git a/tests/baselines/reference/classExpressionAssignment.types b/tests/baselines/reference/classExpressionAssignment.types new file mode 100644 index 00000000000..cfbf796d76d --- /dev/null +++ b/tests/baselines/reference/classExpressionAssignment.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/classExpressionAssignment.ts === +interface A { + prop: string; +>prop : string +} + +// This is invalid +const A: {new(): A} = class {} +>A : new () => A +>class {} : typeof A + diff --git a/tests/cases/compiler/classExpressionAssignment.ts b/tests/cases/compiler/classExpressionAssignment.ts new file mode 100644 index 00000000000..4ad56188a76 --- /dev/null +++ b/tests/cases/compiler/classExpressionAssignment.ts @@ -0,0 +1,6 @@ +interface A { + prop: string; +} + +// This is invalid +const A: {new(): A} = class {}