Using new on a function doesn't work unless merged with an interface. Why?

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 .


The TypeScript type system does know this is a new-able constructor function.

Instead of a function and an interface, you can define it as a single class.

class Bar {
  f = 100;
} 

let x = new Bar();
console.log(x.f);

If you are targeting es5 the generated code will essentially be the same as the constructor function in your question.

链接地址: http://www.djcxy.com/p/37924.html

上一篇: 熊猫系列矢量化查找到字典

下一篇: 除非与接口合并,否则在函数上使用新函数将不起作用。 为什么?