0

下面是带有事件监听器的 Vue 组件类,它可以在某个时间点接收服务工作者的实例并将其保存在registration属性下。

我遇到的问题是,即使这样做:

if (this.registration && this.registration.waiting) {
  this.registration.waiting.postMessage(SERVICE_WORKER_MESSAGES.skipWaiting)
}

TypeScript 传达这this.registrationTS2571: Object is of type 'unknown'.有道理的,因为: private registration: unknown

如果有人能建议什么是初始化和访问稍后可以定义的属性的正确方法,我将不胜感激?

PS:实际的类型registrationServiceWorkerRegistration

类实现:

export default class Core extends Vue {
  private refreshing = false
  private updateExists = false
  private registration: unknown

  updateApp (): void {
    this.updateExists = false

    // this.registration --> TS2571: Object is of type 'unknown'.
    if (this.registration && this.registration.waiting) {
      //                     ~~~~~~~~~~~~~~~~~  

      // this.registration --> TS2571: Object is of type 'unknown'.
      this.registration.waiting.postMessage(SERVICE_WORKER_MESSAGES.skipWaiting)
      // ~~~~~~~~~~~~~~
    }
  }

  addEventListeners () {
    document.addEventListener(SERVICE_WORKER_EVENTS.updated, ((event: CustomEvent) => {
      this.registration = event.detail /* store the ServiceWorkerRegistration instance for later use. */
      this.updateExists = true
    }) as EventListener,
    { once: true })
  }

  created () {
    this.addEventListeners()

    /*
    Refresh all open app tabs when a new service worker is installed */
    navigator.serviceWorker.addEventListener(`controllerchange`, () => {
      if (!this.refreshing) {
        this.refreshing = true
        window.location.reload()
      }
    })
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "sourceMap": true,
    "noImplicitThis": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
4

1 回答 1

1

由于registration在创建实例时没有初始化它可以是undefined.

您可以将其标记为可选

private registration?: ServiceWorkerRegistration

或明确指定它可以是undefined

private registration: ServiceWorkerRegistration | undefined

使用非空断言运算符实际上是一个坏主意,因为它允许访问this.registration属性而不检查它是否已定义/初始化。

于 2020-04-19T10:23:33.970 回答