From 861de5056a7c977b505c279a65e75f0169912533 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 8 Nov 2018 16:36:51 -0800 Subject: [PATCH 1/2] Ensure all default type params are mapped to some default even in circular scenarios --- src/compiler/checker.ts | 6 +- .../reference/subclassThisTypeAssignable.js | 34 +++++++ .../subclassThisTypeAssignable.symbols | 92 +++++++++++++++++++ .../subclassThisTypeAssignable.types | 49 ++++++++++ .../compiler/subclassThisTypeAssignable.ts | 24 +++++ 5 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/subclassThisTypeAssignable.js create mode 100644 tests/baselines/reference/subclassThisTypeAssignable.symbols create mode 100644 tests/baselines/reference/subclassThisTypeAssignable.types create mode 100644 tests/cases/compiler/subclassThisTypeAssignable.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 103200600b219..7cb4c60b399a1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7663,8 +7663,10 @@ namespace ts { // 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 cicrularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType)); for (let i = numTypeArguments; i < numTypeParameters; i++) { - result[i] = getConstraintFromTypeParameter(typeParameters![i]) || getDefaultTypeArgumentType(isJavaScriptImplicitAny); + result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, cicrularityMapper); } for (let i = numTypeArguments; i < numTypeParameters; i++) { const mapper = createTypeMapper(typeParameters!, result); @@ -7672,7 +7674,7 @@ namespace ts { if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) { defaultType = anyType; } - result[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny); + result[i] = defaultType ? instantiateType(defaultType, mapper) : baseDefaultType; } result.length = typeParameters!.length; return result; diff --git a/tests/baselines/reference/subclassThisTypeAssignable.js b/tests/baselines/reference/subclassThisTypeAssignable.js new file mode 100644 index 0000000000000..e374b56e10b4f --- /dev/null +++ b/tests/baselines/reference/subclassThisTypeAssignable.js @@ -0,0 +1,34 @@ +//// [subclassThisTypeAssignable.ts] +interface Lifecycle { + oninit?(vnode: Vnode): number; + [_: number]: any; +} + +interface Vnode = Lifecycle> { + 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(); + +//// [subclassThisTypeAssignable.js] +var C = /** @class */ (function () { + function C() { + } + C.prototype.view = function (v) { return 0; }; + return C; +}()); +var test8 = new C(); diff --git a/tests/baselines/reference/subclassThisTypeAssignable.symbols b/tests/baselines/reference/subclassThisTypeAssignable.symbols new file mode 100644 index 0000000000000..e6fe66cf3d30b --- /dev/null +++ b/tests/baselines/reference/subclassThisTypeAssignable.symbols @@ -0,0 +1,92 @@ +=== tests/cases/compiler/subclassThisTypeAssignable.ts === +interface Lifecycle { +>Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 0, 20)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 0, 26)) + + oninit?(vnode: Vnode): number; +>oninit : Symbol(Lifecycle.oninit, Decl(subclassThisTypeAssignable.ts, 0, 35)) +>vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 1, 9)) +>Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 0, 20)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 0, 26)) + + [_: number]: any; +>_ : Symbol(_, Decl(subclassThisTypeAssignable.ts, 2, 2)) +} + +interface Vnode = Lifecycle> { +>Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) +>Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) +>Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) + + tag: Component; +>tag : Symbol(Vnode.tag, Decl(subclassThisTypeAssignable.ts, 5, 89)) +>Component : Symbol(Component, Decl(subclassThisTypeAssignable.ts, 7, 1)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) +} + +interface Component { +>Component : Symbol(Component, Decl(subclassThisTypeAssignable.ts, 7, 1)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 9, 20)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 9, 26)) + + view(this: State, vnode: Vnode): number; +>view : Symbol(Component.view, Decl(subclassThisTypeAssignable.ts, 9, 35)) +>this : Symbol(this, Decl(subclassThisTypeAssignable.ts, 10, 6)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 9, 26)) +>vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 10, 18)) +>Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) +>Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 9, 20)) +>State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 9, 26)) +} + +interface ClassComponent extends Lifecycle> { +>ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) +>A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) +>Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) +>A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) +>ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) +>A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) + + oninit?(vnode: Vnode): number; +>oninit : Symbol(ClassComponent.oninit, Decl(subclassThisTypeAssignable.ts, 13, 69)) +>vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 14, 9)) +>Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) +>A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) + + view(vnode: Vnode): number; +>view : Symbol(ClassComponent.view, Decl(subclassThisTypeAssignable.ts, 14, 40)) +>vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 15, 6)) +>Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) +>A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) +} + +interface MyAttrs { id: number } +>MyAttrs : Symbol(MyAttrs, Decl(subclassThisTypeAssignable.ts, 16, 1)) +>id : Symbol(MyAttrs.id, Decl(subclassThisTypeAssignable.ts, 18, 19)) + +class C implements ClassComponent { +>C : Symbol(C, Decl(subclassThisTypeAssignable.ts, 18, 32)) +>ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) +>MyAttrs : Symbol(MyAttrs, Decl(subclassThisTypeAssignable.ts, 16, 1)) + + view(v: Vnode) { return 0; } +>view : Symbol(C.view, Decl(subclassThisTypeAssignable.ts, 19, 44)) +>v : Symbol(v, Decl(subclassThisTypeAssignable.ts, 20, 6)) +>Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) +>MyAttrs : Symbol(MyAttrs, Decl(subclassThisTypeAssignable.ts, 16, 1)) +} + +const test8: ClassComponent = new C(); +>test8 : Symbol(test8, Decl(subclassThisTypeAssignable.ts, 23, 5)) +>ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) +>C : Symbol(C, Decl(subclassThisTypeAssignable.ts, 18, 32)) + diff --git a/tests/baselines/reference/subclassThisTypeAssignable.types b/tests/baselines/reference/subclassThisTypeAssignable.types new file mode 100644 index 0000000000000..2a375f0b9a112 --- /dev/null +++ b/tests/baselines/reference/subclassThisTypeAssignable.types @@ -0,0 +1,49 @@ +=== tests/cases/compiler/subclassThisTypeAssignable.ts === +interface Lifecycle { + oninit?(vnode: Vnode): number; +>oninit : (vnode: Vnode) => number +>vnode : Vnode + + [_: number]: any; +>_ : number +} + +interface Vnode = Lifecycle> { + tag: Component; +>tag : Component +} + +interface Component { + view(this: State, vnode: Vnode): number; +>view : (this: State, vnode: Vnode) => number +>this : State +>vnode : Vnode +} + +interface ClassComponent extends Lifecycle> { + oninit?(vnode: Vnode): number; +>oninit : (vnode: Vnode) => number +>vnode : Vnode + + view(vnode: Vnode): number; +>view : (vnode: Vnode) => number +>vnode : Vnode +} + +interface MyAttrs { id: number } +>id : number + +class C implements ClassComponent { +>C : C + + view(v: Vnode) { return 0; } +>view : (v: Vnode>>) => number +>v : Vnode>> +>0 : 0 +} + +const test8: ClassComponent = new C(); +>test8 : ClassComponent +>new C() : C +>C : typeof C + diff --git a/tests/cases/compiler/subclassThisTypeAssignable.ts b/tests/cases/compiler/subclassThisTypeAssignable.ts new file mode 100644 index 0000000000000..bdaa0e6c4a2c0 --- /dev/null +++ b/tests/cases/compiler/subclassThisTypeAssignable.ts @@ -0,0 +1,24 @@ +interface Lifecycle { + oninit?(vnode: Vnode): number; + [_: number]: any; +} + +interface Vnode = Lifecycle> { + 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(); \ No newline at end of file From ac6c89fde6e8dc395eafdffaca0b9294f296e0e4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 9 Nov 2018 15:12:04 -0800 Subject: [PATCH 2/2] Add js example, fix typo --- src/compiler/checker.ts | 4 +- .../reference/subclassThisTypeAssignable.js | 13 +- .../subclassThisTypeAssignable.symbols | 124 +++++++++--------- .../subclassThisTypeAssignable.types | 9 +- .../compiler/subclassThisTypeAssignable.ts | 9 +- 5 files changed, 94 insertions(+), 65 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7cb4c60b399a1..f831a157483c6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7664,9 +7664,9 @@ namespace ts { // 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 cicrularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType)); + const circularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType)); for (let i = numTypeArguments; i < numTypeParameters; i++) { - result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, cicrularityMapper); + result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper); } for (let i = numTypeArguments; i < numTypeParameters; i++) { const mapper = createTypeMapper(typeParameters!, result); diff --git a/tests/baselines/reference/subclassThisTypeAssignable.js b/tests/baselines/reference/subclassThisTypeAssignable.js index e374b56e10b4f..b82e4462a0514 100644 --- a/tests/baselines/reference/subclassThisTypeAssignable.js +++ b/tests/baselines/reference/subclassThisTypeAssignable.js @@ -1,4 +1,6 @@ -//// [subclassThisTypeAssignable.ts] +//// [tests/cases/compiler/subclassThisTypeAssignable.ts] //// + +//// [tile1.ts] interface Lifecycle { oninit?(vnode: Vnode): number; [_: number]: any; @@ -23,8 +25,12 @@ class C implements ClassComponent { } const test8: ClassComponent = new C(); +//// [file1.js] +/** @type {ClassComponent} */ +const test9 = new C(); + -//// [subclassThisTypeAssignable.js] +//// [tile1.js] var C = /** @class */ (function () { function C() { } @@ -32,3 +38,6 @@ var C = /** @class */ (function () { return C; }()); var test8 = new C(); +//// [file1.js] +/** @type {ClassComponent} */ +var test9 = new C(); diff --git a/tests/baselines/reference/subclassThisTypeAssignable.symbols b/tests/baselines/reference/subclassThisTypeAssignable.symbols index e6fe66cf3d30b..8cfc25b28a66c 100644 --- a/tests/baselines/reference/subclassThisTypeAssignable.symbols +++ b/tests/baselines/reference/subclassThisTypeAssignable.symbols @@ -1,92 +1,98 @@ -=== tests/cases/compiler/subclassThisTypeAssignable.ts === +=== tests/cases/compiler/tile1.ts === interface Lifecycle { ->Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 0, 20)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 0, 26)) +>Lifecycle : Symbol(Lifecycle, Decl(tile1.ts, 0, 0)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 0, 20)) +>State : Symbol(State, Decl(tile1.ts, 0, 26)) oninit?(vnode: Vnode): number; ->oninit : Symbol(Lifecycle.oninit, Decl(subclassThisTypeAssignable.ts, 0, 35)) ->vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 1, 9)) ->Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 0, 20)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 0, 26)) +>oninit : Symbol(Lifecycle.oninit, Decl(tile1.ts, 0, 35)) +>vnode : Symbol(vnode, Decl(tile1.ts, 1, 9)) +>Vnode : Symbol(Vnode, Decl(tile1.ts, 3, 1)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 0, 20)) +>State : Symbol(State, Decl(tile1.ts, 0, 26)) [_: number]: any; ->_ : Symbol(_, Decl(subclassThisTypeAssignable.ts, 2, 2)) +>_ : Symbol(_, Decl(tile1.ts, 2, 2)) } interface Vnode = Lifecycle> { ->Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) ->Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) ->Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) +>Vnode : Symbol(Vnode, Decl(tile1.ts, 3, 1)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 5, 16)) +>State : Symbol(State, Decl(tile1.ts, 5, 22)) +>Lifecycle : Symbol(Lifecycle, Decl(tile1.ts, 0, 0)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 5, 16)) +>State : Symbol(State, Decl(tile1.ts, 5, 22)) +>Lifecycle : Symbol(Lifecycle, Decl(tile1.ts, 0, 0)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 5, 16)) +>State : Symbol(State, Decl(tile1.ts, 5, 22)) tag: Component; ->tag : Symbol(Vnode.tag, Decl(subclassThisTypeAssignable.ts, 5, 89)) ->Component : Symbol(Component, Decl(subclassThisTypeAssignable.ts, 7, 1)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 5, 16)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 5, 22)) +>tag : Symbol(Vnode.tag, Decl(tile1.ts, 5, 89)) +>Component : Symbol(Component, Decl(tile1.ts, 7, 1)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 5, 16)) +>State : Symbol(State, Decl(tile1.ts, 5, 22)) } interface Component { ->Component : Symbol(Component, Decl(subclassThisTypeAssignable.ts, 7, 1)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 9, 20)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 9, 26)) +>Component : Symbol(Component, Decl(tile1.ts, 7, 1)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 9, 20)) +>State : Symbol(State, Decl(tile1.ts, 9, 26)) view(this: State, vnode: Vnode): number; ->view : Symbol(Component.view, Decl(subclassThisTypeAssignable.ts, 9, 35)) ->this : Symbol(this, Decl(subclassThisTypeAssignable.ts, 10, 6)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 9, 26)) ->vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 10, 18)) ->Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) ->Attrs : Symbol(Attrs, Decl(subclassThisTypeAssignable.ts, 9, 20)) ->State : Symbol(State, Decl(subclassThisTypeAssignable.ts, 9, 26)) +>view : Symbol(Component.view, Decl(tile1.ts, 9, 35)) +>this : Symbol(this, Decl(tile1.ts, 10, 6)) +>State : Symbol(State, Decl(tile1.ts, 9, 26)) +>vnode : Symbol(vnode, Decl(tile1.ts, 10, 18)) +>Vnode : Symbol(Vnode, Decl(tile1.ts, 3, 1)) +>Attrs : Symbol(Attrs, Decl(tile1.ts, 9, 20)) +>State : Symbol(State, Decl(tile1.ts, 9, 26)) } interface ClassComponent extends Lifecycle> { ->ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) ->A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) ->Lifecycle : Symbol(Lifecycle, Decl(subclassThisTypeAssignable.ts, 0, 0)) ->A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) ->ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) ->A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) +>ClassComponent : Symbol(ClassComponent, Decl(tile1.ts, 11, 1)) +>A : Symbol(A, Decl(tile1.ts, 13, 25)) +>Lifecycle : Symbol(Lifecycle, Decl(tile1.ts, 0, 0)) +>A : Symbol(A, Decl(tile1.ts, 13, 25)) +>ClassComponent : Symbol(ClassComponent, Decl(tile1.ts, 11, 1)) +>A : Symbol(A, Decl(tile1.ts, 13, 25)) oninit?(vnode: Vnode): number; ->oninit : Symbol(ClassComponent.oninit, Decl(subclassThisTypeAssignable.ts, 13, 69)) ->vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 14, 9)) ->Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) ->A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) +>oninit : Symbol(ClassComponent.oninit, Decl(tile1.ts, 13, 69)) +>vnode : Symbol(vnode, Decl(tile1.ts, 14, 9)) +>Vnode : Symbol(Vnode, Decl(tile1.ts, 3, 1)) +>A : Symbol(A, Decl(tile1.ts, 13, 25)) view(vnode: Vnode): number; ->view : Symbol(ClassComponent.view, Decl(subclassThisTypeAssignable.ts, 14, 40)) ->vnode : Symbol(vnode, Decl(subclassThisTypeAssignable.ts, 15, 6)) ->Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) ->A : Symbol(A, Decl(subclassThisTypeAssignable.ts, 13, 25)) +>view : Symbol(ClassComponent.view, Decl(tile1.ts, 14, 40)) +>vnode : Symbol(vnode, Decl(tile1.ts, 15, 6)) +>Vnode : Symbol(Vnode, Decl(tile1.ts, 3, 1)) +>A : Symbol(A, Decl(tile1.ts, 13, 25)) } interface MyAttrs { id: number } ->MyAttrs : Symbol(MyAttrs, Decl(subclassThisTypeAssignable.ts, 16, 1)) ->id : Symbol(MyAttrs.id, Decl(subclassThisTypeAssignable.ts, 18, 19)) +>MyAttrs : Symbol(MyAttrs, Decl(tile1.ts, 16, 1)) +>id : Symbol(MyAttrs.id, Decl(tile1.ts, 18, 19)) class C implements ClassComponent { ->C : Symbol(C, Decl(subclassThisTypeAssignable.ts, 18, 32)) ->ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) ->MyAttrs : Symbol(MyAttrs, Decl(subclassThisTypeAssignable.ts, 16, 1)) +>C : Symbol(C, Decl(tile1.ts, 18, 32)) +>ClassComponent : Symbol(ClassComponent, Decl(tile1.ts, 11, 1)) +>MyAttrs : Symbol(MyAttrs, Decl(tile1.ts, 16, 1)) view(v: Vnode) { return 0; } ->view : Symbol(C.view, Decl(subclassThisTypeAssignable.ts, 19, 44)) ->v : Symbol(v, Decl(subclassThisTypeAssignable.ts, 20, 6)) ->Vnode : Symbol(Vnode, Decl(subclassThisTypeAssignable.ts, 3, 1)) ->MyAttrs : Symbol(MyAttrs, Decl(subclassThisTypeAssignable.ts, 16, 1)) +>view : Symbol(C.view, Decl(tile1.ts, 19, 44)) +>v : Symbol(v, Decl(tile1.ts, 20, 6)) +>Vnode : Symbol(Vnode, Decl(tile1.ts, 3, 1)) +>MyAttrs : Symbol(MyAttrs, Decl(tile1.ts, 16, 1)) } const test8: ClassComponent = new C(); ->test8 : Symbol(test8, Decl(subclassThisTypeAssignable.ts, 23, 5)) ->ClassComponent : Symbol(ClassComponent, Decl(subclassThisTypeAssignable.ts, 11, 1)) ->C : Symbol(C, Decl(subclassThisTypeAssignable.ts, 18, 32)) +>test8 : Symbol(test8, Decl(tile1.ts, 23, 5)) +>ClassComponent : Symbol(ClassComponent, Decl(tile1.ts, 11, 1)) +>C : Symbol(C, Decl(tile1.ts, 18, 32)) + +=== tests/cases/compiler/file1.js === +/** @type {ClassComponent} */ +const test9 = new C(); +>test9 : Symbol(test9, Decl(file1.js, 1, 5)) +>C : Symbol(C, Decl(tile1.ts, 18, 32)) diff --git a/tests/baselines/reference/subclassThisTypeAssignable.types b/tests/baselines/reference/subclassThisTypeAssignable.types index 2a375f0b9a112..711b0056277f8 100644 --- a/tests/baselines/reference/subclassThisTypeAssignable.types +++ b/tests/baselines/reference/subclassThisTypeAssignable.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/subclassThisTypeAssignable.ts === +=== tests/cases/compiler/tile1.ts === interface Lifecycle { oninit?(vnode: Vnode): number; >oninit : (vnode: Vnode) => number @@ -47,3 +47,10 @@ const test8: ClassComponent = new C(); >new C() : C >C : typeof C +=== tests/cases/compiler/file1.js === +/** @type {ClassComponent} */ +const test9 = new C(); +>test9 : ClassComponent +>new C() : C +>C : typeof C + diff --git a/tests/cases/compiler/subclassThisTypeAssignable.ts b/tests/cases/compiler/subclassThisTypeAssignable.ts index bdaa0e6c4a2c0..a582fd0f4c30b 100644 --- a/tests/cases/compiler/subclassThisTypeAssignable.ts +++ b/tests/cases/compiler/subclassThisTypeAssignable.ts @@ -1,3 +1,7 @@ +// @allowJs: true +// @checkJs: true +// @outDir: ./out +// @filename: tile1.ts interface Lifecycle { oninit?(vnode: Vnode): number; [_: number]: any; @@ -21,4 +25,7 @@ class C implements ClassComponent { view(v: Vnode) { return 0; } } -const test8: ClassComponent = new C(); \ No newline at end of file +const test8: ClassComponent = new C(); +// @filename: file1.js +/** @type {ClassComponent} */ +const test9 = new C();