This is all assuming noImplicityAny
is set to true
.
Given this:
function Bar() {
this.f = 100;
}
this doesn't work:
let x = new Bar();
The error you get is:
'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.
OK, I guess that kind of makes sense.
However, if I add an interface to the mix, it works fine:
interface Bar {
f: number;
}
function Bar() {
this.f = 100;
}
let x = new Bar();
console.log(x.f);
When hovering over Bar
you see this as the type:
interface Bar function Bar(): void
So I get that there's some merging going on. I'm just unclear as to why this works now? What exactly is this new merged type, and why is the return type of the Bar()
function no longer implied to be any
?
What you're experiencing is Declaration Merging in TypeScript. Basically if two entities have same declared name, TypeScript merges them together into a single entity. This allows you to do some powerful things like writing declarations and interfaces for 3rd party JavaScript libraries to make them type aware.
In your first example, the compiler knows the return type of Bar()
, which is void
. It doesn't however know what constructor returns so new Bar()
is assumed to be any
.
But when you declare an interface of the same name, the compiler merges the interface Bar
with function Bar()
, and the interface now defines a shape which resembles the function, so the compiler picks it up as the type of new Bar()
. Note that type of Bar()
still stays void
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With