考虑到稍后将动态分配它的值,如何正确初始化 class 的 属性?
How to properly initialise property of the class considering that it's value will be assigned later dynamically?
下面是带有事件侦听器的 Vue 组件 class,它可以在某个时间点接收 service worker 的实例并将其保存在 registration
属性.
我遇到的问题是即使这样做:
if (this.registration && this.registration.waiting) {
this.registration.waiting.postMessage(SERVICE_WORKER_MESSAGES.skipWaiting)
}
TypeScript 表示 this.registration
是 TS2571: Object is of type 'unknown'.
,这是有道理的,因为:
private registration: unknown
如果有人可以建议什么是初始化和访问可以稍后定义的属性的正确方法,我将不胜感激?
P.S:registration
的实际类型是ServiceWorkerRegistration
Class 实施:
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"
]
}
由于在创建实例时未初始化 registration
,因此可以是 undefined
。
你可以标记为optional:
private registration?: ServiceWorkerRegistration
或者明确指定可以是undefined
:
private registration: ServiceWorkerRegistration | undefined
使用非空断言运算符实际上是一个 坏主意,因为它允许访问 this.registration
属性而不检查它是否为 defined/initialized。
下面是带有事件侦听器的 Vue 组件 class,它可以在某个时间点接收 service worker 的实例并将其保存在 registration
属性.
我遇到的问题是即使这样做:
if (this.registration && this.registration.waiting) {
this.registration.waiting.postMessage(SERVICE_WORKER_MESSAGES.skipWaiting)
}
TypeScript 表示 this.registration
是 TS2571: Object is of type 'unknown'.
,这是有道理的,因为:
private registration: unknown
如果有人可以建议什么是初始化和访问可以稍后定义的属性的正确方法,我将不胜感激?
P.S:registration
的实际类型是ServiceWorkerRegistration
Class 实施:
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"
]
}
由于在创建实例时未初始化 registration
,因此可以是 undefined
。
你可以标记为optional:
private registration?: ServiceWorkerRegistration
或者明确指定可以是undefined
:
private registration: ServiceWorkerRegistration | undefined
使用非空断言运算符实际上是一个 坏主意,因为它允许访问 this.registration
属性而不检查它是否为 defined/initialized。