[英]TypeScript type definitions for ServiceWorker
我正在使用 TypeScript 为我的 angular 2 应用程序编写服务。该服务使用 chrome 的ServiceWorker
来侦听推送通知(请参阅教程)。 代码(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)定义定义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 的新手,我正在尝试确定继续进行的最佳方式。 我理解的选项是:
serviceWorker
定义库,并在编译期间包含它。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 编写定义。 但是以前从未做过,所以需要一些练习!
现在可以从DefinitelyTyped / service_worker_api获得ServiceWorker和朋友的类型定义:
$ typings install dt~service_worker_api --global --save
service_worker_api
└── (No dependencies)
用法示例:
// data-access.service.ts
/// <reference path="typings/globals/service_worker_api/index.d.ts" />
import { Injectable } from '@angular/core';
@Injectable()
export class DataAccess {
constructor() {
navigator.serviceWorker.register('service-worker.js', { scope: '/api/' });
}
}
根据需要调整路径。
原始答案
以下是我创建的与WebStorm一起使用的打字: Gist 。
然后在我的service-worker.ts文件中包含一个引用: /// <reference path="YOUR_PATH_HERE/service-worker.d.ts" />
。
相应地调整您的路径,或使它们全局化,您应该设置得相当漂亮。 它相当完整,但我确定它缺少一些东西。 无论如何,我希望这会有所帮助。
2018年更新:
我发布了这些定义的新版本,以及lib.webworker.d.ts以及任何es5 +库(lib.es5.d.ts,lib.es2015.d.ts等): Service Worker Typings to Supplement lib .webworker.d.ts 。 这个集合今天应该更加重要。
您可以在TypeScript文件中添加接口,并在更新lib.d.ts时,编译器会告诉您不再需要它。
interface Navigator {
getUserMedia(
options: { video?: bool; audio?: bool; },
success: (stream: any) => void,
error?: (error: string) => void
) : void;
}
navigator.getUserMedia(
{video: true, audio: true},
function (stream) { },
function (error) { }
);
要么
您可以使用arbitray参数调用any
对象,而不是更改定义,例如:
var n = <any>navigator;
n.getUserMedia = n.getUserMedia || n.webkitGetUserMedia || n.mozGetUserMedia || n.msGetUserMedia;
return n.getUserMedia({video: true, audio:true}, onSuccess, onFail);
ServiceWorker不是特定于chrome的扩展。
OP应该参考Jake Archibald的isSERVICEWORKERready? 有关流行浏览器中ServiceWorker当前状态的详细信息页面。
我根据OP 链接的接口信息在tsd.d.ts
添加了类型定义,它们似乎正在工作。
请注意 ,我从angular.d.ts引用了IPromise
接口。
在tsd.d.ts
定义
/// <reference path="angularjs/angular.d.ts" />
interface Navigator {
serviceWorker: ServiceWorkerContainer;
}
interface ServiceWorkerContainer {
register(scriptUrl: string, options?: RegistrationOptions): angular.IPromise<ServiceWorkerRegistration>;
}
interface RegistrationOptions {
scope: string;
}
interface ServiceWorkerRegistration {
installing?: ServiceWorker;
waiting?: ServiceWorker;
active?: ServiceWorker;
scope: string;
update(): angular.IPromise<void>;
unregister(): angular.IPromise<boolean>;
}
interface ServiceWorker {
scriptUrl: string;
state: string;
postMessage(message: any, transfer: Array<any>): void;
}
在home-controller.ts
提到
///<reference path='../../typings/tsd.d.ts' />
...
// dependencies are injected via AngularJS $injector
constructor() {
var vm = this;
vm.ctrlName = 'HomeCtrl';
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', { scope: '/' }).then(function(reg) {
// registration worked
console.log('Registration succeeded. Scope is ' + reg.scope);
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
} else {
console.warn('serviceWorker not available in navigator.');
}
}
在chrome中构建和加载应用程序
记录以下控制台消息:
希望这可以帮助。
您现在可以直接在 javascript 中为 Service Worker 使用类型,而无需安装额外的包:
// @ts-check
/// <reference no-default-lib="true"/>
/// <reference lib="webworker" />
(
/** @param worker {ServiceWorkerGlobalScope} */
(worker) => {
worker.addEventListener('install', (event) => {
// ...
});
})(/** @type {any} */(self) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.