我通过google.maps
使用google地图JS API和npm install @types/googlemaps
命名空间。我相信API是动态加载的,因此google.maps
JS全局不会立即可用。
但是当我尝试使用Uncaught ReferenceError: google is not defined
但不是google.maps.Marker
来扩展class
时,我不明白为什么会出现运行时错误interface
// No problem!
export interface UuidMarker extends google.maps.Marker {
uuid: string;
}
// Uncaught ReferenceError: google is not defined!!
export class UuidMarker0 extends google.maps.Marker {
uuid: string;
constructor(uuid: string, options?: gmMarkerOptions) {
super(options);
this.uuid = uuid;
}
}
仅使用界面的替代方法
// this works
export function UuidMarkerFactory(uuid: string, marker: google.maps.Marker): google.maps.Marker & {uuid:string} {
return Object.assign(marker, {uuid});
}
// this fails with google is not defined!!
export function UuidMarkerFactory0(uuid: string, options?: any): google.maps.Marker & {uuid:string} {
if (typeof google == "undefined") return null
return Object.assign(new google.maps.Marker(options), {uuid});
}
扩展动态加载的类的最佳做法是什么?
其他信息
我使用ionic2@RC0
使用rollup
捆绑所有模块。我的所有打字稿和node_modules
都捆绑在一个带有源地图的main.js
脚本中。实际的Google Maps API由angular2-google-maps
脚本加载。
如果我使用interface
(似乎更多的打字稿和#34;友好")扩展,我可以使用哪种模式来创建适合UuidMarker
界面的对象?
答案 0 :(得分:7)
在编译过程中,您没有收到任何错误,因为编译器可以访问您使用google.maps
安装的@types
定义。
但是,在运行时,您的文件可能在google.maps
库加载之前被加载,因此解释器无法找到google.maps.Marker
对象。
只有在知道google.maps
文件已成功加载后才需要加载文件。
您不会因UuidMarker
接口而获得运行时错误,因为它在运行时不存在。
接口不存在于javascript中,它们仅由打字稿编译器使用,并且不被"翻译"进入js。
你可以通过将类定义放在函数中来做一个技巧 通过这种方式,解释器在调用此函数之前不会执行它,这可以在google maps lib加载之后执行:
interface UuidMarker extends google.maps.Marker {
uuid: string;
}
let UuidMarker0: { new (uuid: string, options?: gmMarkerOptions): UuidMarker };
function classLoader() {
UuidMarker0 = class UuidMarker0 extends google.maps.Marker implements UuidMarker {
uuid: string;
constructor(uuid: string, options?: gmMarkerOptions) {
super(options);
this.uuid = uuid;
}
}
}
(playground code which simulates this)
另一种方法是按照你的建议放弃课程,然后执行:
function UuidMarker(uuid: string, marker: google.maps.Marker): google.maps.Marker & { uuid: string } {
return Object.assign(marker, { uuid });
}
此语法:
type MyType = google.maps.Marker & { uuid: string };
被称为Intersection Types,这意味着MyType
包含google.maps.Marker
所拥有的所有内容以及uuid
属性。
一个简单的例子:
interface Point {
x: number;
y: number;
}
type Point3D = Point & { z: number };
let p1: Point = { x: 0, y: 0 };
let p2: Point3D = { x: 0, y: 0, z: 0 };