From 2177792a3c34d0e86bccb894c6d89dc1e1e3e8db Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Fri, 5 Jan 2024 12:52:24 +0900
Subject: [PATCH] refactor(frontend): reduce type errors

---
 packages/frontend/src/components/MkTimeline.vue  | 16 ++++++++++------
 .../src/components/MkTokenGenerateWindow.vue     |  4 ++--
 packages/frontend/src/components/MkTooltip.vue   |  3 ++-
 packages/frontend/src/components/MkUpdated.vue   | 10 +++++-----
 4 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue
index 23afb922f3..d5adc02ca7 100644
--- a/packages/frontend/src/components/MkTimeline.vue
+++ b/packages/frontend/src/components/MkTimeline.vue
@@ -11,13 +11,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 		:pagination="paginationQuery"
 		:noGap="!defaultStore.state.showGapBetweenNotesInTimeline"
 		@queue="emit('queue', $event)"
-		@status="prComponent.setDisabled($event)"
+		@status="prComponent?.setDisabled($event)"
 	/>
 </MkPullToRefresh>
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, onUnmounted, provide, ref } from 'vue';
+import { computed, watch, onUnmounted, provide, ref, shallowRef } from 'vue';
 import { Connection } from 'misskey-js/built/streaming.js';
 import MkNotes from '@/components/MkNotes.vue';
 import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
@@ -62,12 +62,14 @@ type TimelineQueryType = {
   roleId?: string
 }
 
-const prComponent = ref<InstanceType<typeof MkPullToRefresh>>();
-const tlComponent = ref<InstanceType<typeof MkNotes>>();
+const prComponent = shallowRef<InstanceType<typeof MkPullToRefresh>>();
+const tlComponent = shallowRef<InstanceType<typeof MkNotes>>();
 
 let tlNotesCount = 0;
 
-const prepend = note => {
+function prepend(note) {
+	if (tlComponent.value == null) return;
+
 	tlNotesCount++;
 
 	if (instance.notesPerOneAd > 0 && tlNotesCount % instance.notesPerOneAd === 0) {
@@ -81,7 +83,7 @@ const prepend = note => {
 	if (props.sound) {
 		sound.play($i && (note.userId === $i.id) ? 'noteMy' : 'note');
 	}
-};
+}
 
 let connection: Connection;
 let connection2: Connection;
@@ -246,6 +248,8 @@ onUnmounted(() => {
 
 function reloadTimeline() {
 	return new Promise<void>((res) => {
+		if (tlComponent.value == null) return;
+
 		tlNotesCount = 0;
 
 		tlComponent.value.pagingComponent?.reload().then(() => {
diff --git a/packages/frontend/src/components/MkTokenGenerateWindow.vue b/packages/frontend/src/components/MkTokenGenerateWindow.vue
index 8e8e26ed5f..d024e1e593 100644
--- a/packages/frontend/src/components/MkTokenGenerateWindow.vue
+++ b/packages/frontend/src/components/MkTokenGenerateWindow.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	:withOkButton="true"
 	:okButtonDisabled="false"
 	:canClose="false"
-	@close="dialog.close()"
+	@close="dialog?.close()"
 	@closed="$emit('closed')"
 	@ok="ok()"
 >
@@ -87,7 +87,7 @@ function ok(): void {
 		name: name.value,
 		permissions: Object.keys(permissions.value).filter(p => permissions.value[p]),
 	});
-	dialog.value.close();
+	dialog.value?.close();
 }
 
 function disableAll(): void {
diff --git a/packages/frontend/src/components/MkTooltip.vue b/packages/frontend/src/components/MkTooltip.vue
index d21c6317aa..ea22175e03 100644
--- a/packages/frontend/src/components/MkTooltip.vue
+++ b/packages/frontend/src/components/MkTooltip.vue
@@ -31,7 +31,7 @@ const props = withDefaults(defineProps<{
 	targetElement?: HTMLElement;
 	x?: number;
 	y?: number;
-	text?: string;
+	text: string;
 	asMfm?: boolean;
 	maxWidth?: number;
 	direction?: 'top' | 'bottom' | 'right' | 'left';
@@ -53,6 +53,7 @@ const el = shallowRef<HTMLElement>();
 const zIndex = os.claimZIndex('high');
 
 function setPosition() {
+	if (!el.value || !props.targetElement) return;
 	const data = calcPopupPosition(el.value, {
 		anchorElement: props.targetElement,
 		direction: props.direction,
diff --git a/packages/frontend/src/components/MkUpdated.vue b/packages/frontend/src/components/MkUpdated.vue
index 391733931a..29403a84b3 100644
--- a/packages/frontend/src/components/MkUpdated.vue
+++ b/packages/frontend/src/components/MkUpdated.vue
@@ -4,12 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<MkModal ref="modal" :zPriority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
+<MkModal ref="modal" :zPriority="'middle'" @click="modal?.close()" @closed="$emit('closed')">
 	<div :class="$style.root">
 		<div :class="$style.title"><MkSparkle>{{ i18n.ts.misskeyUpdated }}</MkSparkle></div>
 		<div :class="$style.version">✨{{ version }}🚀</div>
 		<MkButton full @click="whatIsNew">{{ i18n.ts.whatIsNew }}</MkButton>
-		<MkButton :class="$style.gotIt" primary full @click="$refs.modal.close()">{{ i18n.ts.gotIt }}</MkButton>
+		<MkButton :class="$style.gotIt" primary full @click="modal?.close()">{{ i18n.ts.gotIt }}</MkButton>
 	</div>
 </MkModal>
 </template>
@@ -25,10 +25,10 @@ import { confetti } from '@/scripts/confetti.js';
 
 const modal = shallowRef<InstanceType<typeof MkModal>>();
 
-const whatIsNew = () => {
-	modal.value.close();
+function whatIsNew() {
+	modal.value?.close();
 	window.open(`https://misskey-hub.net/docs/releases/#_${version.replace(/\./g, '')}`, '_blank');
-};
+}
 
 onMounted(() => {
 	confetti({