Last active
June 3, 2024 07:00
-
-
Save tiernan/11a40d253a55a5c5ff518d6deae3ee48 to your computer and use it in GitHub Desktop.
Typings for using the Service Worker API with TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* DEPRECIATED: Please use the updated type definitions: | |
* Service Worker Typings to Supplement lib.webworker.d.ts | |
* https://gist.github.com/tiernan/c18a380935e45a6d942ac1e88c5bbaf3 | |
* | |
* | |
* Copyright (c) 2016, Tiernan Cridland | |
* | |
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby | |
* granted, provided that the above copyright notice and this permission notice appear in all copies. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL | |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | |
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
* PERFORMANCE OF THIS SOFTWARE. | |
* | |
* DEPRECIATED: Typings for Service Worker circa 2016 | |
* @author Tiernan Cridland | |
* @email tiernanc@gmail.com | |
* @license: ISC | |
* | |
* 2018 Update: | |
* If this file is used in combination with lib.webworker.d.ts you will receive many errors. | |
* It can still be used with the current lib.es5.d.ts; however, I recommend using the new edition listed at the top of | |
* this file along with lib.webworker.d.ts and an es5+ library (es5, es2015, etc). | |
* | |
* This gist will no longer be maintained. | |
*/ | |
interface Navigator { | |
serviceWorker: ServiceWorkerContainer; | |
} | |
interface ExtendableEvent extends Event { | |
waitUntil(fn: Promise<any>): void; | |
} | |
interface ServiceWorker extends Worker { | |
scriptURL: string; | |
state: ServiceWorkerState; | |
} | |
interface ServiceWorkerContainer { | |
controller?: ServiceWorker; | |
oncontrollerchange?: (event?: Event) => any; | |
onerror?: (event?: Event) => any; | |
onmessage?: (event?: Event) => any; | |
ready: Promise<ServiceWorkerRegistration>; | |
getRegistration(scope?: string): Promise<ServiceWorkerRegistration>; | |
getRegistrations(): Promise<Array<ServiceWorkerRegistration>>; | |
register(url: string, options?: ServiceWorkerRegistrationOptions): Promise<ServiceWorkerRegistration>; | |
} | |
interface ServiceWorkerNotificationOptions { | |
tag?: string; | |
} | |
interface ServiceWorkerRegistration { | |
active?: ServiceWorker; | |
installing?: ServiceWorker; | |
onupdatefound?: (event?: Event) => any; | |
pushManager: PushManager; | |
scope: string; | |
waiting?: ServiceWorker; | |
getNotifications(options?: ServiceWorkerNotificationOptions): Promise<Array<Notification>>; | |
update(): void; | |
unregister(): Promise<boolean>; | |
} | |
interface ServiceWorkerRegistrationOptions { | |
scope?: string; | |
} | |
type ServiceWorkerState = "installing" | "installed" | "activating" | "activated" | "redundant"; | |
// CacheStorage API | |
interface Cache { | |
add(request: Request): Promise<void>; | |
addAll(requestArray: Array<Request>): Promise<void>; | |
'delete'(request: Request, options?: CacheStorageOptions): Promise<boolean>; | |
keys(request?: Request, options?: CacheStorageOptions): Promise<Array<string>>; | |
match(request: Request, options?: CacheStorageOptions): Promise<Response>; | |
matchAll(request: Request, options?: CacheStorageOptions): Promise<Array<Response>>; | |
put(request: Request|string, response: Response): Promise<void>; | |
} | |
interface CacheStorage { | |
'delete'(cacheName: string): Promise<boolean>; | |
has(cacheName: string): Promise<boolean>; | |
keys(): Promise<Array<string>>; | |
match(request: Request, options?: CacheStorageOptions): Promise<Response>; | |
open(cacheName: string): Promise<Cache>; | |
} | |
interface CacheStorageOptions { | |
cacheName?: string; | |
ignoreMethod?: boolean; | |
ignoreSearch?: boolean; | |
ignoreVary?: boolean; | |
} | |
// Client API | |
interface Client { | |
frameType: ClientFrameType; | |
id: string; | |
url: string; | |
} | |
interface Clients { | |
claim(): Promise<any>; | |
get(id: string): Promise<Client>; | |
matchAll(options?: ClientMatchOptions): Promise<Array<Client>>; | |
openWindow(url: string): Promise<WindowClient>; | |
} | |
interface ClientMatchOptions { | |
includeUncontrolled?: boolean; | |
type?: ClientMatchTypes; | |
} | |
interface WindowClient { | |
focused: boolean; | |
visibilityState: WindowClientState; | |
focus(): Promise<WindowClient>; | |
navigate(url: string): Promise<WindowClient>; | |
} | |
type ClientFrameType = "auxiliary" | "top-level" | "nested" | "none"; | |
type ClientMatchTypes = "window" | "worker" | "sharedworker" | "all"; | |
type WindowClientState = "hidden" | "visible" | "prerender" | "unloaded"; | |
// Events | |
interface InstallEvent extends ExtendableEvent { | |
activeWorker: ServiceWorker; | |
} | |
interface ActivateEvent extends ExtendableEvent { | |
} | |
// Fetch API | |
interface Body { | |
bodyUsed: boolean; | |
arrayBuffer(): Promise<ArrayBuffer>; | |
blob(): Promise<Blob>; | |
formData(): Promise<FormData>; | |
json(): Promise<any>; | |
text(): Promise<string>; | |
} | |
interface FetchEvent extends ExtendableEvent { | |
clientId: string; | |
request: Request; | |
respondWith(response: Promise<Response>|Response): Promise<Response>; | |
} | |
interface Headers { | |
new(init?: any): Headers; | |
append(name: string, value: string): void; | |
'delete'(name: string): void; | |
entries(): Array<Array<string>>; | |
get(name: string): string; | |
getAll(name: string): Array<string>; | |
has(name: string): boolean; | |
keys(): Array<string>; | |
set(name: string, value: string): void; | |
values(): Array<string>; | |
} | |
interface Request extends Body { | |
new(url: string, init?: { | |
method?: string, | |
url?: string, | |
referrer?: string, | |
mode?: RequestMode, | |
credentials?: RequestCredentials, | |
redirect?: RequestRedirect, | |
integrity?: string, | |
cache?: RequestCache, | |
headers?: Headers | |
}): Request; | |
cache: RequestCache; | |
credentials: RequestCredentials; | |
headers: Headers; | |
integrity: string; | |
method: string; | |
mode: RequestMode; | |
referrer: string; | |
referrerPolicy: ReferrerPolicy; | |
redirect: RequestRedirect; | |
url: string; | |
clone(): Request; | |
} | |
interface Response extends Body { | |
new(url: string): Response; | |
new(body: Blob|BufferSource|FormData|String, init: { | |
status?: number, | |
statusText?: string, | |
headers?: Headers|{ [k: string]: string } | |
}): Response; | |
headers: Headers; | |
ok: boolean; | |
redirected: boolean; | |
status: number; | |
statusText: string; | |
type: ResponseType; | |
url: string; | |
useFinalURL: boolean; | |
clone(): Response; | |
error(): Response; | |
redirect(): Response; | |
} | |
// Notification API | |
interface Notification { | |
body: string; | |
data: any; | |
icon: string; | |
lang: string; | |
requireInteraction: boolean; | |
silent: boolean; | |
tag: string; | |
timestamp: number; | |
title: string; | |
close(): void; | |
requestPermission(): Promise<string>; | |
} | |
interface NotificationEvent { | |
action: string; | |
notification: Notification; | |
} | |
// Push API | |
interface PushEvent extends ExtendableEvent { | |
data: PushMessageData; | |
} | |
interface PushManager { | |
getSubscription(): Promise<PushSubscription>; | |
permissionState(): Promise<string>; | |
subscribe(): Promise<PushSubscription>; | |
} | |
interface PushMessageData { | |
arrayBuffer(): ArrayBuffer; | |
blob(): Blob; | |
json(): any; | |
text(): string; | |
} | |
interface PushSubscription { | |
endpoint: string; | |
getKey(method: string): ArrayBuffer; | |
toJSON(): string; | |
unsubscribe(): Promise<boolean>; | |
} | |
// Sync API | |
interface SyncEvent extends Event { | |
lastChance: boolean; | |
tag: string; | |
} | |
// ServiceWorkerGlobalScope | |
declare var Headers: Headers; | |
declare var Response: Response; | |
declare var Request: Request; | |
declare var caches: CacheStorage; | |
declare var clients: Clients; | |
declare var onactivate: (event?: ActivateEvent) => any; | |
declare var onfetch: (event?: FetchEvent) => any; | |
declare var oninstall: (event?: InstallEvent) => any; | |
declare var onmessage: (event: MessageEvent) => any; | |
declare var onnotificationclick: (event?: NotificationEvent) => any; | |
declare var onnotificationclose: (event?: NotificationEvent) => any; | |
declare var onpush: (event?: PushEvent) => any; | |
declare var onpushsubscriptionchange: () => any; | |
declare var onsync: (event?: SyncEvent) => any; | |
declare var registration: ServiceWorkerRegistration; | |
declare function fetch(request: Request|string): Promise<Response>; | |
declare function skipWaiting(): void; | |
In TypeScript, the new method is specifically reserved as a constructor identifier and should therefore only be used within classes and not in interfaces. One way around this problem is to create a class that implements the interface.
I have an edited version of this file for those who want to use it in this version.
Expand service-worker.d.ts
interface Navigator {
serviceWorker: ServiceWorkerContainer
}
interface ExtendableEvent extends Event {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
waitUntil(fn: Promise<any>): void
}
interface ServiceWorker extends Worker {
scriptURL: string
state: ServiceWorkerState
}
interface ServiceWorkerContainer {
controller?: ServiceWorker
/* eslint-disable @typescript-eslint/no-explicit-any */
oncontrollerchange?: (event?: Event) => any
onerror?: (event?: Event) => any
onmessage?: (event?: Event) => any
/* eslint-enable @typescript-eslint/no-explicit-any */
ready: Promise<ServiceWorkerRegistration>
getRegistration(scope?: string): Promise<ServiceWorkerRegistration>
getRegistrations(): Promise<Array<ServiceWorkerRegistration>>
register(url: string, options?: ServiceWorkerRegistrationOptions): Promise<ServiceWorkerRegistration>
}
interface ServiceWorkerNotificationOptions {
tag?: string
}
interface ServiceWorkerRegistration {
active?: ServiceWorker
installing?: ServiceWorker
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onupdatefound?: (event?: Event) => any
pushManager: PushManager
scope: string
waiting?: ServiceWorker
getNotifications(options?: ServiceWorkerNotificationOptions): Promise<Array<Notification>>
update(): void
unregister(): Promise<boolean>
}
interface ServiceWorkerRegistrationOptions {
scope?: string
}
type ServiceWorkerState = 'installing' | 'installed' | 'activating' | 'activated' | 'redundant'
// CacheStorage API
interface Cache {
add(request: Request): Promise<void>
addAll(requestArray: Array<Request>): Promise<void>
'delete'(request: Request, options?: CacheStorageOptions): Promise<boolean>
keys(request?: Request, options?: CacheStorageOptions): Promise<Array<string>>
match(request: Request, options?: CacheStorageOptions): Promise<Response>
matchAll(request: Request, options?: CacheStorageOptions): Promise<Array<Response>>
put(request: Request | string, response: Response): Promise<void>
}
interface CacheStorage {
'delete'(cacheName: string): Promise<boolean>
has(cacheName: string): Promise<boolean>
keys(): Promise<Array<string>>
match(request: Request, options?: CacheStorageOptions): Promise<Response>
open(cacheName: string): Promise<Cache>
}
interface CacheStorageOptions {
cacheName?: string
ignoreMethod?: boolean
ignoreSearch?: boolean
ignoreVary?: boolean
}
// Client API
interface Client {
frameType: ClientFrameType
id: string
url: string
}
interface Clients {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
claim(): Promise<any>
get(id: string): Promise<Client>
matchAll(options?: ClientMatchOptions): Promise<Array<Client>>
openWindow(url: string): Promise<WindowClient>
}
interface ClientMatchOptions {
includeUncontrolled?: boolean
type?: ClientMatchTypes
}
interface WindowClient {
focused: boolean
visibilityState: WindowClientState
focus(): Promise<WindowClient>
navigate(url: string): Promise<WindowClient>
}
type ClientFrameType = 'auxiliary' | 'top-level' | 'nested' | 'none'
type ClientMatchTypes = 'window' | 'worker' | 'sharedworker' | 'all'
type WindowClientState = 'hidden' | 'visible' | 'prerender' | 'unloaded'
// Fetch API
interface Body {
bodyUsed: boolean
arrayBuffer(): Promise<ArrayBuffer>
blob(): Promise<Blob>
formData(): Promise<FormData>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
json(): Promise<any>
text(): Promise<string>
}
interface FetchEvent extends Event {
request: Request
respondWith(response: Promise<Response> | Response): Promise<Response>
}
interface InstallEvent extends ExtendableEvent {
activeWorker: ServiceWorker
}
type ActivateEvent = ExtendableEvent
interface HeadersInit {
[name: string]: string
}
interface Headers {
append(name: string, value: string): void
delete(name: string): void
entries(): IterableIterator<[string, string]>
get(name: string): string | null
has(name: string): boolean
set(name: string, value: string): void
keys(): IterableIterator<string>
values(): IterableIterator<string>
}
interface HeadersConstructor {
new(init?: HeadersInit): Headers
}
interface RequestInit {
cache?: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache'
credentials?: 'omit' | 'same-origin' | 'include'
headers?: Headers
integrity?: string
method?: string
mode?: 'cors' | 'no-cors' | 'same-origin' | 'navigate'
redirect?: 'follow' | 'error' | 'manual'
referrer?: string
url?: string
}
interface Request {
cache: RequestCache
credentials: RequestCredentials
headers: Headers
integrity: string
method: string
mode: RequestMode
redirect: RequestRedirect
referrer: string
referrerPolicy: ReferrerPolicy
url: string
clone(): Request
}
interface RequestConstructor {
new(
url: string,
init?: RequestInit,
): Request
}
interface ResponseInit {
headers?: Headers | { [key: string]: string }
status?: number
statusText?: string
}
interface Response extends Body {
headers: Headers
ok: boolean
redirected: boolean
status: number
statusText: string
type: ResponseType
url: string
useFinalURL: boolean
clone(): Response
error(): Response
redirect(url: string, status?: number): Response
}
interface ResponseConstructor {
new(body?: Blob | BufferSource | FormData | string, init?: ResponseInit): Response
}
type ReferrerPolicy = '' | 'no-referrer' | 'no-referrer-when-downgrade' | 'origin-only' | 'origin-when-cross-origin' |
'unsafe-url'
type RequestCache = 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache'
type RequestCredentials = 'omit' | 'same-origin' | 'include'
type RequestMode = 'cors' | 'no-cors' | 'same-origin' | 'navigate'
type RequestRedirect = 'follow' | 'error' | 'manual'
type ResponseType = 'basic' | 'cores' | 'error' | 'opaque'
// Notification API
interface Notification {
body: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data: any
icon: string
lang: string
requireInteraction: boolean
silent: boolean
tag: string
timestamp: number
title: string
close(): void
requestPermission(): Promise<string>
}
interface NotificationEvent {
action: string
notification: Notification
}
// Push API
interface PushEvent extends ExtendableEvent {
data: PushMessageData
}
interface PushManager {
getSubscription(): Promise<PushSubscription>
permissionState(): Promise<string>
subscribe(): Promise<PushSubscription>
}
interface PushMessageData {
arrayBuffer(): ArrayBuffer
blob(): Blob
// eslint-disable-next-line @typescript-eslint/no-explicit-any
json(): any
text(): string
}
interface PushSubscription {
endpoint: string
getKey(method: string): ArrayBuffer
toJSON(): string
unsubscribe(): Promise<boolean>
}
// Sync API
interface SyncEvent extends Event {
lastChance: boolean
tag: string
}
// ServiceWorkerGlobalScope
/* eslint-disable no-var */
declare var Headers: Headers
declare var Response: Response
declare var Request: Request
/* eslint-enable no-var */
declare let caches: CacheStorage
declare let clients: Clients
/* eslint-disable @typescript-eslint/no-explicit-any */
declare let onactivate: (event?: ExtendableEvent) => any
declare let onfetch: (event?: FetchEvent) => any
declare let oninstall: (event?: ExtendableEvent) => any
declare let onmessage: (event: MessageEvent) => any
declare let onnotificationclick: (event?: NotificationEvent) => any
declare let onnotificationclose: (event?: NotificationEvent) => any
declare let onpush: (event?: PushEvent) => any
declare let onpushsubscriptionchange: () => any
declare let onsync: (event?: SyncEvent) => any
/* eslint-enable @typescript-eslint/no-explicit-any */
declare let registration: ServiceWorkerRegistration
declare function fetch(request: Request | string): Promise<Response>
declare function skipWaiting(): void
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tank you @tiernan and @IAMtheIAM .
simple and update way as @IAMtheIAM say : https://github.com/angular/angular/blob/master/packages/service-worker/worker/src/service-worker.d.ts