2016-07-03 21 views
5

Tôi đang viết một dịch vụ cho ứng dụng góc 2 của mình bằng cách sử dụng TypeScript. Dịch vụ này sử dụng số ServiceWorker của chrome để nghe thông báo đẩy (xem tutorial). Mã (javascript) tận dụng navigator đầu tiên để xem nếu serviceWorker được hỗ trợ, sau đó tiếp tục hoàn tất đăng ký, vv, nghĩa là,Định nghĩa kiểu TypeScript cho 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); 
    }); 
} 

Tôi muốn implemenet ở trên sử dụng nguyên cảo. Tuy nhiên, hiện tại lib.d.ts được sử dụng bởi trình biên dịch TypeScript (xem bên dưới) dường như không có định nghĩa nào được xác định trên Navigator cho serviceWorker hoặc các phương pháp liên quan của nó chẳng hạn như serviceWorker.register (Tôi đoán vì đó là triển khai cụ thể cho 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; 
} 

Kết quả là tôi phải đối mặt với lỗi biên dịch vì trình biên dịch không thể tìm thấy loại serviceWorker được liên kết. Do tôi mới sử dụng JavaScript và TypeScript, tôi đang cố gắng xác định cách tốt nhất để tiếp tục. Tôi hiểu các tùy chọn là:

  1. Giữ mã js và chỉ cần bỏ qua lỗi biên dịch (không phải lý tưởng).
  2. Giữ mã js và bằng cách nào đó loại bỏ các lỗi loại trong khi biên soạn .
  3. Tìm thư viện định nghĩa kiểu chữ hiện có mà có serviceWorker được xác định và bao gồm trong quá trình biên dịch.
  4. Viết tập tin định nghĩa nguyên cảo của riêng mình cho hoa tiêu hoặc bằng cách nào đó mở rộng hiện lib.d.ts

Sage tư vấn về lựa chọn tốt nhất đánh giá rất cao.

Cập nhật

Đã cố gắng để cast cho bất kỳ để loại bỏ lỗi biên dịch, tức là,

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); 
    }); 

nhưng bây giờ phải đối mặt với lỗi mới, tức là,

error TS7006: Parameter 'reg' implicitly has an 'any' type. 
error TS7006: Parameter 'error' implicitly has an 'any' type. 

Ngoài ra, cám dỗ để viết định nghĩa cho ServiceWorker bằng cách sử dụng các details này. Tuy nhiên không bao giờ thực hiện nó trước, vì vậy sẽ cần một số thực hành!

Trả lời

1

Bạn có thể thêm vào giao diện trong tệp TypeScript của mình và khi lib.d.ts được cập nhật, trình biên dịch sẽ cho bạn biết rằng bạn không còn cần đến nó nữa.

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) { } 
); 

hoặc

Thay vì thay đổi định nghĩa bạn có thể đúc đến một đối tượng any một cuộc gọi với các thông số arbitray ví dụ:

var n = <any>navigator; 
    n.getUserMedia = n.getUserMedia || n.webkitGetUserMedia || n.mozGetUserMedia || n.msGetUserMedia; 
    return n.getUserMedia({video: true, audio:true}, onSuccess, onFail); 
+0

Đúc sẽ là giải pháp đơn giản nhất, tuy nhiên, cố gắng truyền tới '' đưa ra lỗi 'TS7006: Tham số 'reg' ngầm có một loại 'bất kỳ'. - xem cập nhật. –

1

ServiceWorker không phải là một phần mở rộng cụ thể chrome.

OP nên tham khảo trang isSERVICEWORKERready? của Jake Archibald để biết tóm tắt trạng thái hiện tại của ServiceWorker trong các trình duyệt phổ biến.

Tôi đã thêm định nghĩa kiểu trong tsd.d.ts dựa trên thông tin giao diện linked bởi OP và chúng dường như đang hoạt động.

Xin lưu ý mà tôi đã tham chiếu IPromise giao diện từ angular.d.ts.

Defined trong 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; 
} 

giới thiệu trong 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.'); 
    } 
} 

Xây dựng và tải các ứng dụng trong chrome

enter image description here

đăng thông điệp điều khiển sau:

enter image description here

Hy vọng điều này sẽ hữu ích.

2

Dưới đây là các Kiểu chữ tôi đã tạo để sử dụng với WebStorm: Gist.

Sau đó, trong tệp service-worker.ts của tôi, tôi bao gồm tham chiếu: /// <reference path="YOUR_PATH_HERE/service-worker.d.ts" />.

Điều chỉnh đường dẫn của bạn cho phù hợp, hoặc biến chúng thành toàn cầu và bạn sẽ được thiết lập đẹp mắt. Nó khá hoàn chỉnh, nhưng tôi chắc chắn nó thiếu một số thứ. Dù sao, tôi hy vọng điều này sẽ giúp.

+1

Điều này thật tuyệt! Thực hiện một vài cập nhật (từng phần): https://gist.github.com/ithinkihaveacat/227bfe8aa81328c5d64ec48f4e4df8e5 – mjs

+0

@mjs Cảm ơn sự đóng góp của bạn! Tôi đã kéo các thay đổi của bạn với một số thay đổi nhỏ. – tiernanx

5

Loại định nghĩa cho ServiceWorker and friends đang có sẵn từ DefinitelyTyped/service_worker_api:

$ typings install dt~service_worker_api --global --save 
service_worker_api 
└── (No dependencies) 

Cách sử dụng Ví dụ:

// 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/' }); 
    } 
} 

Điều chỉnh các đường dẫn khi cần thiết.

+1

Kể từ TypeScript 2.0, 'npm install --save @ types/service_worker_api' [cũng sẽ hoạt động] (https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration -các tập tin/). – mjs

+0

@mjs Đó là một cải tiến rất tốt đẹp. –

Các vấn đề liên quan