&引用;建造商;在typescript接口中
我从正在使用的库中收到以下界面:&引用;建造商;在typescript接口中,typescript,Typescript,我从正在使用的库中收到以下界面: export interface LatLng { constructor(lat: number, lng: number): void; lat(): number; lng(): number; } 如何创建此类的实现?(我需要一个测试模拟)一个外观自然的实现,构造函数定义为: export class LatLngImpl implements LatLng { constructor(private _lat: number, pri
export interface LatLng {
constructor(lat: number, lng: number): void;
lat(): number;
lng(): number;
}
如何创建此类的实现?(我需要一个测试模拟)一个外观自然的实现,构造函数定义为:
export class LatLngImpl implements LatLng {
constructor(private _lat: number, private _lng: number) { }
不编译:
类“LatLngImpl”不正确地实现了接口“LatLng”。
属性“构造函数”的类型不兼容。
类型“功能”不可分配给类型“(纬度:编号,液化天然气:编号)=>>void”。
类型“Function”不提供与签名匹配的内容(lat:number,lng:>number):void'
我在typescript中读到了constructor接口,但我认为它在这里不适用
编辑:
我不理解的是接口中的
constructor()
声明。带有构造函数签名的接口使用new()
语法。我认为不能将构造函数放入接口中
interface IPerson
{
firstName: string;
lastName: string;
}
class Person implements IPerson
{
constructor (public firstName: string, public lastName: string)
{
//TODO
}
}
var personA: IPerson = new Person('Jane', 'Smith');
var personB: IPerson = { firstName: 'Jo', lastName: 'Smith' };
从技术上讲,构造函数是一种特殊的静态函数调用,它返回自身的实例,因此它作为接口的一部分实际上没有意义,因为接口成员是实例绑定的 Typescript有一点编译器技巧使它们静态绑定,并将其用于环境声明 在您的情况下,要提供实现,您需要从接口中删除构造函数:
interface LatLng {
lat(): number;
lng(): number;
}
class LatLngImpl implements LatLng {
constructor(lat: number, lng: number) {
}
lat(): number {
return 0;
}
lng(): number {
return 0;
}
}
如果LatLng
在其他地方实现,则只需提供环境声明:
interface LatLng {
lat(): number;
lng(): number;
}
interface LatLngConstructor {
new(lat: number, lng: number): LatLng;
}
declare var LatLng: LatLngConstructor;
请注意,
LatLngConstructor
定义了一个new(…):LatLng
,它描述了构造函数签名。这个库来自哪里?不管是谁写的,都应该受到严厉的批评。要么是一个错误(在这种情况下,他们从未测试过它),要么是故意的,但很卑鄙:使用构造函数作为实例方法的标识符只是自找麻烦
编辑2019-04-25:麻烦不仅仅是“这是个坏主意”;实际上,它看起来像是一旦JavaScript本机支持类字段。TypeScript将更改以在3.5+版本中反映这一点,因此下面的实现将停止工作。有关更多信息,请参阅最近打开的GitHub问题。在TS3.5之后,似乎没有办法让一个类的实例构造函数属性本身不是实际的构造函数
要么库作者打算引用您使用new
调用的真实构造函数,在这种情况下,他们应该执行类似@Series0ne的操作;或者作者确实想使用实例方法来初始化对象,在这种情况下,他们应该帮每个人的忙,使用更传统的方法名称,如init()
在任何一种情况下,都不应该有人接受您提供的接口,当然也不应该有人实现它
让我们实施它:
export class LatLngImpl implements LatLng {
private _lat: number;
private _lng: number;
lat() {
return this._lat;
}
lng() {
return this._lng;
}
// here's the important part, but see Microsoft/TypeScript#31020
"constructor"(lat: number, lng: number) {
this._lat = lat;
this._lng = lng;
}
}
诀窍是使用字符串literal“constructor”
而不是裸词constructor
。从:
字符串文字可用于提供无效标识符的属性名称
通过使用字符串文字,我们能够将其声明为实例方法,而不是在调用new
时调用的静态类构造函数方法,并且它可以顺利编译
现在我们可以使用它,如果我们敢:
const latLng=new LatLngImpl();
建造商(47.6391132,-122.1284311);//更正式地说,一个实现接口的类是一个关于该类实例拥有什么的契约。由于类的实例不包含构造签名,因此它不能满足接口要求Ryan Cavanaugh是的,我理解'new():MyInterface'的工作原理。但在该库中,它被声明为“constructor():void”。我怀疑这是某种错误。接口中的声明将其视为一个普通函数,而在类中,构造函数是一个保留字。重要的是,接口
是关于确保创建什么,而不是它是如何到达那里的。根据我的经验,强迫构造器以某种方式运行只会带来更多的痛苦,而没有任何实际的好处。i、 例如,任何正在消费的LatLngImpl
都只关心lat
和lng
属性,而构造函数细节应该是无关的。任何更严格的要求都可能是错误代码的标志。