【问题标题】:Property 'errorCode' does not exist on type 'EventTarget'“EventTarget”类型上不存在属性“errorCode”
【发布时间】:2021-07-23 13:41:21
【问题描述】:

我正在制作一个具有多个使用 IndexDB 的功能的服务工作者。在这些函数中,我收到了这些打字稿错误:

Property 'errorCode' does not exist on type 'EventTarget'

当使用db.onsuccess & db.onerror

这是我的服务工作者代码:

/// <reference no-default-lib="true"/>
/// <reference lib="ES2020" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="webworker" />

export type {};
declare const self: ServiceWorkerGlobalScope;

interface AccessCredentials {
    accessToken: string;
    refreshToken: string;
}

async function getAccessCredentials(): Promise<AccessCredentials> {
    const databaseName = 'BATAccessTokens';
    const databaseStore = 'BATAccessTokens';
    return new Promise((resolve, reject) => {
        const dbrequest = indexedDB.open(databaseName, 1);
        dbrequest.onupgradeneeded = (event) => {
            const database = dbrequest.result;
            database.createObjectStore(databaseStore, { autoIncrement: true });
            database.onerror = () =>
                reject(`ERROR:  ${event.target.errorCode}`);
        };
        dbrequest.onerror = (event) =>
            reject(`ERROR:  ${event.target.errorCode}`);
        dbrequest.onsuccess = (event) => {
            const database = dbrequest.result;
            const transaction = database.transaction(databaseStore, 'readwrite');
            const store = transaction.objectStore(databaseStore);
            const request = store.get(1);
            request.onsuccess = () => {
                if (request.result) resolve(request.result);
                resolve(null);
            };
            transaction.oncomplete = () => database.close();
            database.onerror = () => resolve(null);
        };
    });
}

async function putAccessCredentials(credentials: AccessCredentials) {
    const databaseName = 'BATAccessTokens';
    const databaseStore = 'BATAccessTokens';
    return new Promise((resolve, reject) => {
        const dbrequest = indexedDB.open(databaseName, 1);
        dbrequest.onupgradeneeded = () => {
            const database = dbrequest.result;
            database.createObjectStore(databaseStore, { autoIncrement: true });
            database.onerror = (event) =>
                reject(`ERROR:  ${event.target.errorCode}`);
        };
        dbrequest.onerror = (event) =>
            reject(`ERROR:  ${event.target.errorCode}`);
        dbrequest.onsuccess = (event) => {
            const database = dbrequest.result;
            const transaction = database.transaction(databaseStore, 'readwrite');
            const store = transaction.objectStore(databaseStore);
            const request = store.put(credentials, 1);
            request.onsuccess = () => resolve(credentials);
            transaction.oncomplete = () => database.close();
            database.onerror = () =>
                reject(`ERROR:  ${event.target.errorCode}`);
        };
    });
}

async function putRBDSCode(RBDSCode) {
    const databaseName = 'BATRBDSCode';
    const databaseStore = 'BATRBDSCode';
    return new Promise((resolve, reject) => {
        const dbrequest = indexedDB.open(databaseName, 1);
        dbrequest.onupgradeneeded = () => {
            const database = dbrequest.result;
            database.createObjectStore(databaseStore, { autoIncrement: true });
            database.onerror = (event) =>
                reject(`ERROR:  ${event.target.errorCode}`);
        };
        dbrequest.onerror = (event) =>
            reject(`ERROR:  ${event.target.errorCode}`);
        dbrequest.onsuccess = (event) => {
            const database = dbrequest.result;
            const transaction = database.transaction(databaseStore, 'readwrite');
            const store = transaction.objectStore(databaseStore);
            const request = store.put(RBDSCode, 1);
            request.onsuccess = () => resolve(RBDSCode);
            transaction.oncomplete = () => database.close();
            database.onerror = () =>
                reject(`ERROR:  ${event.target.errorCode}`);
        };
    });
}

async function getClientList(): Promise<readonly WindowClient[]> {
    const clientList = await self.clients.claim().then(() =>
        self.clients.matchAll({
            type: 'window'
        })
    );
    return clientList;
}

self.addEventListener('install', (event) => {
    console.log('Service Worker installed');
});

self.addEventListener('activate', (event) => {
    console.log('Service Worker activated');
});

self.addEventListener('fetch', (event) => {
    if (event.request.method === 'GET' && event.request.mode === 'navigate') {
        let request = event.request;
        // console.log({request});

        event.waitUntil(getClientList());

        event.respondWith((async () => {

            const clientList = await getClientList();
            const client = clientList.find((item) => item.visibilityState === 'visible');
            const url = client && new URL(client.url);
            const rbdsCode = url && url.searchParams.get('RBDSCode');
            const credentials = await getAccessCredentials();

            const dppRequest = false;
            const rbdsRequest = !!rbdsCode && !dppRequest;

            if (rbdsRequest && !credentials) {
                // console.log(client);
                // client.navigate('/forms/login.html').then(() => client.focus())
                request = new Request(`http://localhost:3000/forms/login.html`);
            }

            if (request && credentials) {
                // do something
            }

            if (dppRequest) {
                // handle dpp request
            }

            if (credentials) request = new Request(request, {
                headers: {
                    ...request.headers,
                    Authorization: `Bearer ${credentials.accessToken}`
                }
            });

            const eventResponse = await fetch(request).then((response) => {
                let accessToken, refreshToken;
                for (const header of response.headers.entries()) {
                    if (header[0] === 'accesstoken') accessToken = header[1];
                    if (header[0] === 'refreshtoken') refreshToken = header[1];
                }
                accessToken && refreshToken && putAccessCredentials({ accessToken, refreshToken });
                return response;
            });

            return eventResponse;
        })());
    }
});

【问题讨论】:

  • errorCode 更改为error 有什么不同吗?我问是因为IDBRequest.onerror 下显示的示例使用属性名称error 来获取更多信息 - 并假设error.target 指的是设置.onerror 的(请求)对象。
  • 否,因为这里的函数参数输入到事件,但是我想我找到了使用dbrequest.error.code的解决方法
  • 小心你使用的 typescript 声明文件,许多 typescript 库对 IndexedDB 的类型声明不正确

标签: javascript typescript service-worker indexeddb


【解决方案1】:

解压你看到的错误:

Property 'errorCode' does not exist on type 'EventTarget'

这是有道理的,因为通用 EventTarget(例如 DOM 元素)没有 errorCode 属性。但是 Typescript 在这里并不能帮助您,因为当您编写 event.target.result 时,它显然不知道 Indexed DB 对象的特定接口类型是什么。

在这种情况下,这些事件的target 是一个IDBRequest 实例...没有errorCode 属性。所以无论如何你都会遇到类似的错误。

如您所见,IDBRequest 接口确实有一个error 属性,即DOMException。反过来,DOMException 接口具有code 属性。

也就是说... code 属性已弃用 - 新的 DOMException 类型不定义新代码,因此 code 将始终为 0。如果您需要消除错误,则应使用 DOMException 的 name类型。

【讨论】:

    猜你喜欢
    • 2019-01-28
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 2018-04-30
    • 2021-06-03
    • 2018-01-09
    相关资源
    最近更新 更多