Closed
Description
TypeScript Version: 3.1.0-dev.20180922
Search Terms:
js constructor function
Code
// clazz1c.js
function clazz1c(){
this.constructorOnly = 0 // (1.) [ts] 'this' implicitly has type 'any' because it does not have a type annotation.
this.constructorUnknown = undefined // (1.) [ts] 'this' implicitly has type 'any' because it does not have a type annotation.
}
clazz1c.prototype.method = function() {
this.constructorOnly = 3
this.constructorUnknown = "plunkbat"
}
module.exports=clazz1c
// node-global.ts
/// <reference types="node" />
export {}
import Clazz1cType = require("../clazz1c") // (2.) (alias) function Clazz1cType(): void
var clazz1bGlobalVar: Clazz1bType // (2.) var clazz1bGlobalVar: any
declare global {
namespace NodeJS {
interface Global {
clazz1bGlobalVar: Clazz1cType // (4.) (property) NodeJS.Global.clazz1bGlobalVar: any
}
}
}
// index.js
var clazz1c = require("./clazz1c") // (3.) var clazz1c: typeof clazz1c
var clazz1cInstance = new clazz1c(); // (3.) var clazz1bGlobalVar: any
global.clazz1bGlobalVar=clazz1bInstance // (4.) (property) NodeJS.Global.clazz1bGlobalVar: any
// jsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"checkJs": true,
"noEmit": true,
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"target": "es5",
"baseUrl": ".",
"lib": [
"es2015",
"dom"
]
},
"exclude": [
"node_modules"
],
"typeAcquisition": {
"enable": false
}
}
Expected behavior:
this
inside the constructor is infered based on this-property assignments- function is recognized as constructor function; assignment gives type of
class
? - type equivalent to a class t.i.
(alias) class clazz1c
(per default type is exported too) - typed equivalent to type of constructor function of clazz1c, sth like
new() => clazz1c
?
Actual behavior:
this
inside the constructor is not infered based on this-property assignments- function is not recognized as constructor function; assignment gives
any
type - type is not recognized as equivalent to a class
- typed as any
(2), (3) and (4) not in playground link, but doable as github tag on request
Related Issues:
None found
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
ghost commentedon Sep 25, 2018
I think this is the intended behavior under
noImplicitThis
. There's no good way for us to tell what's a constructor function and what's meant to be a method. If we just assume that any function might be used as a constructor we'll miss out on a lot of errors, as all assignments to an untypedthis
become legal. If you don't care about that and just want your constructor functions to work you could set"noImplicitThis": false
in your jsconfig.joma74 commentedon Sep 25, 2018
@Andy-MS Quoting https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files#constructor-functions-are-equivalent-to-classes, i interpreted that said hold without further hinting or limitations?
If not, i could be fine with annotating the constructor function with the TS comment hint
@constructor
. If this is the case, one should additionally PR the above documentation.In any case, according to the title of this issue, i would like to discuss (2) (3) and (4) as not "working as intended". Neither the resulting TS signature nor the compiler's evaluated/exported type of such a constructor function are currently handled equivalent to a class. On any usage in said ts or js files, the constructor function is still interpreted as sth like
(alias) function clazz1c(): void
, not as a type of a class's equivalent constructor function. So when I assign that as a type to a variable, the variable gets typed asany
. Guess that the compiler does not bring in the proper class-like type, but should do that. What bugs me is that else there is currently no way to type a variable to be of typeclazz1c
in e.g.node-global.ts
, and also all the other effects described above in (2) (3) and (4).P.S. If i rewrite clazz1c to be a proper es2015 class, the exact same usage in said ts or js files works as intended. So this issue aims to get
constructor functions as equivalent to ES2015 classes
recognized by TS in js and ts filesjoma74 commentedon Sep 28, 2018
See also #18171 relating to (1)
ghost commentedon Oct 1, 2018
That document is titled "Type Checking JavaScript Files" -- in JS files the rules are looser by default. But when you set
noImplicitThis
you are opting into stricter typescript-style checking.joma74 commentedon Oct 2, 2018
@Andy-MS Okay, got that. So it has to be
to make
noImplicitThis
give no error. But for the other why parts of Constructor functions are not recognized as equivalent to classes, please considerClazz1cType
is just a(alias) function Clazz1cType(): void
at (A). At (B) it defaults toany
. Because it seems to me thatClazz1cType
gets not conotated as a class-like type, as it would be if it was recognized as equivalent to classes.Even no hand-written declaration like
type Clazz1cType = typeof Clazz1cType
at (C) does make this right, as on the usage in the next file e.g.gives
[ts] Type 'clazz1c' is not assignable to type 'typeof clazz1c'. Type 'clazz1c' provides no match for the signature '(): void'.
at (D)joma74 commentedon Oct 4, 2018
See also #27550.
Although other worded, but may apply here: As in
14 remaining items