我正在使用TypeScript为angular 2应用编写一个服务。该服务使用chrome的ServiceWorker
来监听推送通知(参见tutorial)。代码(javascript)首先使用navigator
来查看是否支持serviceWorker
,然后继续完成注册等,即:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('sw.js').then(function() {
return navigator.serviceWorker.ready;
}).then(function(reg) {
console.log('Service Worker is ready :^)', reg);
// TODO
}).catch(function(error) {
console.log('Service Worker error :^(', error);
});
}
我想用TypeScript实现上面的方法。但是,TypeScript编译器(见下文)使用的当前lib.d.ts
似乎没有在Navigator
上定义serviceWorker
或其相关方法,如serviceWorker.register
(我猜是因为它是一个特定于chrome的实现)。
interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorContentUtils, NavigatorStorageUtils, NavigatorGeolocation, MSNavigatorDoNotTrack, MSFileSaver, NavigatorUserMedia {
readonly appCodeName: string;
readonly cookieEnabled: boolean;
readonly language: string;
readonly maxTouchPoints: number;
readonly mimeTypes: MimeTypeArray;
readonly msManipulationViewsEnabled: boolean;
readonly msMaxTouchPoints: number;
readonly msPointerEnabled: boolean;
readonly plugins: PluginArray;
readonly pointerEnabled: boolean;
readonly webdriver: boolean;
getGamepads(): Gamepad[];
javaEnabled(): boolean;
msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: MediaKeySystemConfiguration[]): PromiseLike<MediaKeySystemAccess>;
vibrate(pattern: number | number[]): boolean;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
结果是,我面临着编译错误,因为编译器找不到相关的serviceWorker
类型。鉴于我是JavaScript和TypeScript的新手,我试图确定最好的方法来继续。我理解的选项是:
1.保留js代码并简单地忽略编译错误(不理想)。
1.保留js代码并在编译期间以某种方式抑制类型错误。
1.找到已定义serviceWorker
的现有类型脚本定义库,并在编译期间将其包括在内。
1.为navigator编写自己的typescript定义文件或以某种方式扩展现有的lib.d.ts
非常感谢关于最佳选择的明智建议。
更新
试图强制转换为any以移除编译错误,即,
var nav = <any> navigator;
if ('serviceWorker' in nav) {
nav.serviceWorker.register('sw.js')
.then(function(reg) {
console.log('yey!', <any> reg);
}).catch(function(err) {
console.log('boo!', <any> err);
});
但现在面临新的错误,
error TS7006: Parameter 'reg' implicitly has an 'any' type.
error TS7006: Parameter 'error' implicitly has an 'any' type.
同时,尝试使用这些细节为ServiceWorker编写定义。但是以前从未这样做过,所以需要一些练习!
4条答案
按热度按时间2hh7jdfx1#
ServiceWorker和friends的类型定义现在可从DefinitelyTyped/service_worker_api获得:
用法示例:
根据需要调整路径。
vdzxcuhz2#
您可以将添加到TypeScript文件中的接口,当lib.d.ts更新时,编译器会告诉您不再需要它。
或
您可以将带有任意参数的调用强制转换为
any
对象,而不必更改定义,例如:chy5wohz3#
ServiceWorker不是特定于Chrome的扩展。
OP应该参考Jake Archibald的isSERVICEWORKERready?页面,了解流行浏览器中ServiceWorker的当前状态。
我根据OP链接的接口信息在
tsd.d.ts
中添加了类型定义,它们似乎正在工作。请注意我从angular.d.ts引用了
IPromise
接口。在
tsd.d.ts
中定义以
home-controller.ts
表示在chrome中构建和加载应用程序
记录以下控制台消息:
希望这对你有帮助。
lmyy7pcs4#
原始答案
以下是我创建的用于WebStorm的类型:Gist。
然后在我的service-worker.ts文件中包含一个引用:
/// <reference path="YOUR_PATH_HERE/service-worker.d.ts" />
.相应地调整你的路径,或者把它们变成全局的,你应该已经很确定了。它相当完整,但是我确信它遗漏了一些东西。无论如何,我希望这能有所帮助。
2018年更新:
我发布了这些定义的新版本,以便与lib.webworker.d.ts沿着任何es 5+库(lib.es5.d.ts、lib.es2015.d.ts等)一起使用:Service Worker Typings to Supplement lib.webworker.d.ts.这一套今天应该更相关。