我一直在使用TypeScript中的构造签名接口,当下面的键盘检查失败时我感到有点困惑:
class Foo {
constructor () {
}
}
interface Bar {
new(): Bar;
}
function Baz(C : Bar) {
return new C()
}
var o = Baz(Foo);
类型错误是:
提供的参数与调用目标的任何签名都不匹配: 构造类型'new()=>的签名Foo'和'Bar'是 不兼容:类型'Bar'需要构造签名,但Type 'Foo'缺少一个(C:Bar)=>杆
Foo构造函数的类型是()=> Foo,这就是我认为Bar所说的。我在这里错过了什么吗?
答案 0 :(得分:5)
以下是代码的更新版本,并进行了细微更改。
我们使用我们期望存在的任何函数和变量来定义Bar
接口。
接下来,我们使用Bar
接口扩展NewableBar
接口。这只是定义了一个返回Bar
。
由于Foo
实施Bar
并且有一个构造函数且Baz
需要NewableBar
,所以一切都会被检查。
这比any
更加冗长 - 但是可以为您提供所需的支票。
interface Bar {
}
interface NewableBar extends Bar {
new();
}
class Foo implements Bar {
constructor () {
}
}
function Baz(C : NewableBar) {
return new C()
}
var o = Baz(Foo);
答案 1 :(得分:1)
问题(至少从TypeScript编译器的角度来看)是Bar
的{{1}}方法的签名。如果您使用以下内容替换new
的定义,
Bar
它有效。您也可以使用interface Bar {
new (): any;
}
,只使用new (): Foo
,因为返回值不起作用。
答案 2 :(得分:1)
我想我知道你在哪里采取这种做法,我认为你需要一种微妙的不同方法。
此示例说明如下:
以下是示例:
interface Bar {
sayHello(name: string): void;
}
interface Newable {
new();
}
class Foo implements Bar {
constructor () {
}
sayHello(name: string) {
window.alert('Hello ' + name);
}
}
function Baz(C : Newable) {
return <Bar> new C()
}
var o = Baz(Foo);
o.sayHello('Bob');
这种方法的唯一危险是你可以将一些不是Bar的新东西传递给Baz函数。当你通过从参数创建一个对象来使用动态特性时,除非你愿意传入一个预先初始化的对象,否则这在很大程度上是不可避免的,在这种情况下,Baz很乐意接受一个Bar,而不是一个新的。 / p>
答案 3 :(得分:1)
我知道这是一个古老的问题,但我今天需要类似的东西并遇到过帖子。经过一些反复试验后,我提出了以下解决方案:
interface Bar {
sayHello(name: string);
}
class Foo implements Bar {
sayHello(name: string) {
window.alert("Hello " + name);
}
}
function Baz(c: new() => Bar) {
return new C();
}
var o = Baz(Foo);
o.sayHello("Bob");
基本上接口只能定义对象实例的契约,因此要求某个构造函数存在必须在将调用构造函数的函数上完成。这种方法也适用于泛型:
function Baz<T extends Bar>(c: new() => T) {
return new c();
}
var o = Baz(Foo);
在上面的例子中变量&#34; o&#34;将被推断为Foo类型。
答案 4 :(得分:0)
真的有一个简单的答案。查看您的Bar
界面:
interface Bar {
new(): Bar;
}
比方说,您已经成功创建了一些实现该接口的Magic
类。
class Magic implements Bar {
// ...
}
这意味着Magic
的任何实例都必须遵守Bar
的规范。因此,假设您有一个名为Magic
的{{1}}实例。
由于magic
符合magic
的规范,因此Bar
必须是可更新的,这意味着以下各项必须有效:
magic
此外,该调用的结果即const foo = new magic() // lowercase m!
必须本身遵守foo
。这意味着以下内容也必须起作用:
Bar
然后很明显,以下内容也必须起作用:
const zzz = new foo();
很明显,您的代码不满足此条件。因此,您的代码不会键入check。