From 154ac342cb01b1c42e8058085f8a22b969fbba6c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 5 Apr 2018 08:52:56 -0700 Subject: [PATCH] Allow extending any, with noImplicitAny errors (#23153) Allow extending any, without noImplicitAny errors --- src/compiler/checker.ts | 3 + ...aintOfJavascriptClassExpression.errors.txt | 5 +- .../reference/classExtendingAny.symbols | 65 ++++++++++++ .../reference/classExtendingAny.types | 99 +++++++++++++++++++ .../reference/thisTypeInFunctions2.errors.txt | 4 +- .../reference/thisTypeInFunctions2.js | 8 +- .../reference/thisTypeInFunctions2.symbols | 4 +- .../reference/thisTypeInFunctions2.types | 8 +- tests/cases/compiler/classExtendingAny.ts | 37 +++++++ .../types/thisType/thisTypeInFunctions2.ts | 4 +- .../TypeScript-Node-Starter | 2 +- 11 files changed, 220 insertions(+), 19 deletions(-) create mode 100644 tests/baselines/reference/classExtendingAny.symbols create mode 100644 tests/baselines/reference/classExtendingAny.types create mode 100644 tests/cases/compiler/classExtendingAny.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4f3419a0e9a..076830b47f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17938,6 +17938,9 @@ namespace ts { function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[]): Signature { if (node.expression.kind === SyntaxKind.SuperKeyword) { const superType = checkSuperExpression(node.expression); + if (isTypeAny(superType)) { + return anySignature; + } if (superType !== unknownType) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. diff --git a/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt b/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt index b409185a114..0b65f4fd3be 100644 --- a/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt +++ b/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt @@ -1,10 +1,9 @@ tests/cases/compiler/weird.js(1,1): error TS2304: Cannot find name 'someFunction'. tests/cases/compiler/weird.js(1,23): error TS7006: Parameter 'BaseClass' implicitly has an 'any' type. -tests/cases/compiler/weird.js(6,13): error TS2346: Call target does not contain any signatures. tests/cases/compiler/weird.js(9,17): error TS7006: Parameter 'error' implicitly has an 'any' type. -==== tests/cases/compiler/weird.js (4 errors) ==== +==== tests/cases/compiler/weird.js (3 errors) ==== someFunction(function(BaseClass) { ~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'someFunction'. @@ -15,8 +14,6 @@ tests/cases/compiler/weird.js(9,17): error TS7006: Parameter 'error' implicitly class Hello extends BaseClass { constructor() { super(); - ~~~~~~~ -!!! error TS2346: Call target does not contain any signatures. this.foo = "bar"; } _render(error) { diff --git a/tests/baselines/reference/classExtendingAny.symbols b/tests/baselines/reference/classExtendingAny.symbols new file mode 100644 index 00000000000..9c3db9ebe2b --- /dev/null +++ b/tests/baselines/reference/classExtendingAny.symbols @@ -0,0 +1,65 @@ +=== tests/cases/compiler/a.ts === +declare var Err: any +>Err : Symbol(Err, Decl(a.ts, 0, 11)) + +class A extends Err { +>A : Symbol(A, Decl(a.ts, 0, 20)) +>Err : Symbol(Err, Decl(a.ts, 0, 11)) + + payload: string +>payload : Symbol(A.payload, Decl(a.ts, 1, 21)) + + constructor() { + super(1,2,3,3,4,56) + super.unknown + super['unknown'] + } + process() { +>process : Symbol(A.process, Decl(a.ts, 7, 5)) + + return this.payload + "!"; +>this.payload : Symbol(A.payload, Decl(a.ts, 1, 21)) +>this : Symbol(A, Decl(a.ts, 0, 20)) +>payload : Symbol(A.payload, Decl(a.ts, 1, 21)) + } +} + +var o = { +>o : Symbol(o, Decl(a.ts, 13, 3)) + + m() { +>m : Symbol(m, Decl(a.ts, 13, 9)) + + super.unknown + } +} +=== tests/cases/compiler/b.js === +class B extends Err { +>B : Symbol(B, Decl(b.js, 0, 0)) +>Err : Symbol(Err, Decl(a.ts, 0, 11)) + + constructor() { + super() + this.wat = 12 +>this.wat : Symbol(B.wat, Decl(b.js, 2, 15)) +>this : Symbol(B, Decl(b.js, 0, 0)) +>wat : Symbol(B.wat, Decl(b.js, 2, 15)) + } + f() { +>f : Symbol(B.f, Decl(b.js, 4, 5)) + + this.wat +>this.wat : Symbol(B.wat, Decl(b.js, 2, 15)) +>this : Symbol(B, Decl(b.js, 0, 0)) +>wat : Symbol(B.wat, Decl(b.js, 2, 15)) + + this.wit +>this : Symbol(B, Decl(b.js, 0, 0)) + + this['wot'] +>this : Symbol(B, Decl(b.js, 0, 0)) + + super.alsoBad + } +} + diff --git a/tests/baselines/reference/classExtendingAny.types b/tests/baselines/reference/classExtendingAny.types new file mode 100644 index 00000000000..fb585ed1de0 --- /dev/null +++ b/tests/baselines/reference/classExtendingAny.types @@ -0,0 +1,99 @@ +=== tests/cases/compiler/a.ts === +declare var Err: any +>Err : any + +class A extends Err { +>A : A +>Err : any + + payload: string +>payload : string + + constructor() { + super(1,2,3,3,4,56) +>super(1,2,3,3,4,56) : void +>super : any +>1 : 1 +>2 : 2 +>3 : 3 +>3 : 3 +>4 : 4 +>56 : 56 + + super.unknown +>super.unknown : any +>super : any +>unknown : any + + super['unknown'] +>super['unknown'] : any +>super : any +>'unknown' : "unknown" + } + process() { +>process : () => string + + return this.payload + "!"; +>this.payload + "!" : string +>this.payload : string +>this : this +>payload : string +>"!" : "!" + } +} + +var o = { +>o : { m(): void; } +>{ m() { super.unknown }} : { m(): void; } + + m() { +>m : () => void + + super.unknown +>super.unknown : any +>super : any +>unknown : any + } +} +=== tests/cases/compiler/b.js === +class B extends Err { +>B : B +>Err : any + + constructor() { + super() +>super() : void +>super : any + + this.wat = 12 +>this.wat = 12 : 12 +>this.wat : number +>this : this +>wat : number +>12 : 12 + } + f() { +>f : () => void + + this.wat +>this.wat : number +>this : this +>wat : number + + this.wit +>this.wit : any +>this : this +>wit : any + + this['wot'] +>this['wot'] : any +>this : this +>'wot' : "wot" + + super.alsoBad +>super.alsoBad : any +>super : any +>alsoBad : any + } +} + diff --git a/tests/baselines/reference/thisTypeInFunctions2.errors.txt b/tests/baselines/reference/thisTypeInFunctions2.errors.txt index f18f4707aa6..cc8afe2f581 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.errors.txt +++ b/tests/baselines/reference/thisTypeInFunctions2.errors.txt @@ -38,12 +38,12 @@ tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts(14,5): error TS70 }); extend2({ init() { - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing this.mine }, mine: 13, foo() { - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing this.mine } }); diff --git a/tests/baselines/reference/thisTypeInFunctions2.js b/tests/baselines/reference/thisTypeInFunctions2.js index 978f79483b0..ccd16f2cc8d 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.js +++ b/tests/baselines/reference/thisTypeInFunctions2.js @@ -33,12 +33,12 @@ extend1({ }); extend2({ init() { - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing this.mine }, mine: 13, foo() { - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing this.mine } }); @@ -68,12 +68,12 @@ extend1({ }); extend2({ init: function () { - this; // this: containing object literal type + this; // this: IndexedWithoutThis because of contextual typing this.mine; }, mine: 13, foo: function () { - this; // this: containing object literal type + this; // this: IndexedWithoutThis because of contextual typing this.mine; } }); diff --git a/tests/baselines/reference/thisTypeInFunctions2.symbols b/tests/baselines/reference/thisTypeInFunctions2.symbols index d4b19caddb4..aeff7756a62 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.symbols +++ b/tests/baselines/reference/thisTypeInFunctions2.symbols @@ -89,7 +89,7 @@ extend2({ init() { >init : Symbol(init, Decl(thisTypeInFunctions2.ts, 32, 9)) - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing >this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) this.mine @@ -102,7 +102,7 @@ extend2({ foo() { >foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 37, 13)) - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing >this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) this.mine diff --git a/tests/baselines/reference/thisTypeInFunctions2.types b/tests/baselines/reference/thisTypeInFunctions2.types index 302f52be3e3..e8df582332a 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.types +++ b/tests/baselines/reference/thisTypeInFunctions2.types @@ -92,14 +92,14 @@ extend1({ } }); extend2({ ->extend2({ init() { this // this: containing object literal type this.mine }, mine: 13, foo() { this // this: containing object literal type this.mine }}) : void +>extend2({ init() { this // this: IndexedWithoutThis because of contextual typing this.mine }, mine: 13, foo() { this // this: IndexedWithoutThis because of contextual typing this.mine }}) : void >extend2 : (args: IndexedWithoutThis) => void ->{ init() { this // this: containing object literal type this.mine }, mine: 13, foo() { this // this: containing object literal type this.mine }} : { init(): void; mine: number; foo(): void; } +>{ init() { this // this: IndexedWithoutThis because of contextual typing this.mine }, mine: 13, foo() { this // this: IndexedWithoutThis because of contextual typing this.mine }} : { init(): void; mine: number; foo(): void; } init() { >init : () => void - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing >this : IndexedWithoutThis this.mine @@ -115,7 +115,7 @@ extend2({ foo() { >foo : () => void - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing >this : IndexedWithoutThis this.mine diff --git a/tests/cases/compiler/classExtendingAny.ts b/tests/cases/compiler/classExtendingAny.ts new file mode 100644 index 00000000000..c2279ea6f7b --- /dev/null +++ b/tests/cases/compiler/classExtendingAny.ts @@ -0,0 +1,37 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @noImplicitAny: true +// @target: es6 +// @Filename: a.ts +declare var Err: any +class A extends Err { + payload: string + constructor() { + super(1,2,3,3,4,56) + super.unknown + super['unknown'] + } + process() { + return this.payload + "!"; + } +} + +var o = { + m() { + super.unknown + } +} +// @Filename: b.js +class B extends Err { + constructor() { + super() + this.wat = 12 + } + f() { + this.wat + this.wit + this['wot'] + super.alsoBad + } +} diff --git a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts index 54dc9fa8a17..612283ac013 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts @@ -35,12 +35,12 @@ extend1({ }); extend2({ init() { - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing this.mine }, mine: 13, foo() { - this // this: containing object literal type + this // this: IndexedWithoutThis because of contextual typing this.mine } }); diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index 40bdb4eadab..ed149eb0c78 160000 --- a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +++ b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter @@ -1 +1 @@ -Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6 +Subproject commit ed149eb0c787b1195a95b44105822c64bb6eb636