diff --git a/packages/frontend/src/components/MkEmojiPicker.section.vue b/packages/frontend/src/components/MkEmojiPicker.section.vue
index 14f3f5770f..43a6664d11 100644
--- a/packages/frontend/src/components/MkEmojiPicker.section.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.section.vue
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <!-- フォルダの中にはカスタム絵文字やフォルダがある -->
 <section v-else v-panel style="border-radius: 6px; border-bottom: 0.5px solid var(--divider);">
 	<header class="_acrylic" @click="shown = !shown">
-		<i class="toggle ti-fw" :class="shown ? 'ti ti-chevron-down' : 'ti ti-chevron-up'"></i> <slot></slot> (<i class="ti ti-folder ti-fw"></i>:{{ customEmojiTree.length }} <i class="ti ti-icons ti-fw"></i>:{{ emojis.length }})
+		<i class="toggle ti-fw" :class="shown ? 'ti ti-chevron-down' : 'ti ti-chevron-up'"></i> <slot></slot> (<i class="ti ti-folder ti-fw"></i>:{{ customEmojiTree?.length }} <i class="ti ti-icons ti-fw"></i>:{{ emojis.length }})
 	</header>
 	<div v-if="shown" style="padding-left: 9px;">
 		<MkEmojiPickerSection
@@ -61,7 +61,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <script lang="ts" setup>
 import { ref, computed, Ref } from 'vue';
 import { CustomEmojiFolderTree, getEmojiName } from '@/scripts/emojilist.js';
-import { i18n } from '../i18n.js';
+import { i18n } from '@/i18n.js';
 import { customEmojis } from '@/custom-emojis.js';
 import MkEmojiPickerSection from '@/components/MkEmojiPicker.section.vue';
 
@@ -87,7 +87,7 @@ function computeButtonTitle(ev: MouseEvent): void {
 	elm.title = getEmojiName(emoji) ?? emoji;
 }
 
-function nestedChosen(emoji: any, ev?: MouseEvent) {
+function nestedChosen(emoji: any, ev: MouseEvent) {
 	emit('chosen', emoji, ev);
 }
 </script>
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index f36d46506f..2db4195b98 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</section>
 
 		<div v-if="tab === 'index'" class="group index">
-			<section v-if="showPinned && pinned.length > 0">
+			<section v-if="showPinned && (pinned && pinned.length > 0)">
 				<div class="body">
 					<button
 						v-for="emoji in pinned"
@@ -327,7 +327,7 @@ watch(q, () => {
 });
 
 function filterAvailable(emoji: Misskey.entities.EmojiSimple): boolean {
-	return (emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.includes(r.id)));
+	return ((emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction?.includes(r.id)))) ?? false;
 }
 
 function focus() {
diff --git a/packages/frontend/src/components/MkFileCaptionEditWindow.vue b/packages/frontend/src/components/MkFileCaptionEditWindow.vue
index 922089a78b..b9d0e34809 100644
--- a/packages/frontend/src/components/MkFileCaptionEditWindow.vue
+++ b/packages/frontend/src/components/MkFileCaptionEditWindow.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	:withOkButton="true"
 	:okButtonDisabled="false"
 	@ok="ok()"
-	@close="dialog.close()"
+	@close="dialog?.close()"
 	@closed="emit('closed')"
 >
 	<template #header>{{ i18n.ts.describeFile }}</template>
@@ -48,6 +48,6 @@ const caption = ref(props.default);
 
 async function ok() {
 	emit('done', caption.value);
-	dialog.value.close();
+	dialog.value?.close();
 }
 </script>
diff --git a/packages/frontend/src/components/MkFileListForAdmin.vue b/packages/frontend/src/components/MkFileListForAdmin.vue
index 3edd30bc37..955a90a50d 100644
--- a/packages/frontend/src/components/MkFileListForAdmin.vue
+++ b/packages/frontend/src/components/MkFileListForAdmin.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div>
 	<MkPagination v-slot="{items}" :pagination="pagination" class="urempief" :class="{ grid: viewMode === 'grid' }">
 		<MkA
-			v-for="file in items"
+			v-for="file in (items as Misskey.entities.DriveFile[])"
 			:key="file.id"
 			v-tooltip.mfm="`${file.type}\n${bytes(file.size)}\n${dateString(file.createdAt)}\nby ${file.user ? '@' + Misskey.acct.toString(file.user) : 'system'}`"
 			:to="`/admin/file/${file.id}`"
diff --git a/packages/frontend/src/components/MkFoldableSection.vue b/packages/frontend/src/components/MkFoldableSection.vue
index 1ffc95d944..1df2df085f 100644
--- a/packages/frontend/src/components/MkFoldableSection.vue
+++ b/packages/frontend/src/components/MkFoldableSection.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<div ref="el" :class="$style.root">
+<div ref="div" :class="$style.root">
 	<header :class="$style.header" class="_button" :style="{ background: bg }" @click="showBody = !showBody">
 		<div :class="$style.title"><div><slot name="header"></slot></div></div>
 		<div :class="$style.divider"></div>
@@ -42,8 +42,8 @@ const props = withDefaults(defineProps<{
 	expanded: true,
 });
 
-const el = shallowRef<HTMLDivElement>();
-const bg = ref<string | null>(null);
+const div = shallowRef<HTMLDivElement>();
+const bg = ref<string>();
 const showBody = ref((props.persistKey && miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`)) ? (miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`) === 't') : props.expanded);
 
 watch(showBody, () => {
@@ -52,40 +52,44 @@ watch(showBody, () => {
 	}
 });
 
-function enter(el: Element) {
+function enter(element: Element) {
+	const el = element as HTMLElement;
 	const elementHeight = el.getBoundingClientRect().height;
-	el.style.height = 0;
+	el.style.height = 'unset';
 	el.offsetHeight; // reflow
 	el.style.height = elementHeight + 'px';
 }
 
-function afterEnter(el: Element) {
-	el.style.height = null;
+function afterEnter(element: Element) {
+	const el = element as HTMLElement;
+	el.style.height = 'unset';
 }
 
-function leave(el: Element) {
+function leave(element: Element) {
+	const el = element as HTMLElement;
 	const elementHeight = el.getBoundingClientRect().height;
 	el.style.height = elementHeight + 'px';
 	el.offsetHeight; // reflow
-	el.style.height = 0;
+	el.style.height = '0';
 }
 
-function afterLeave(el: Element) {
-	el.style.height = null;
+function afterLeave(element: Element) {
+	const el = element as HTMLElement;
+	el.style.height = 'unset';
 }
 
 onMounted(() => {
-	function getParentBg(el: HTMLElement | null): string {
+	function getParentBg(el?: HTMLElement | null): string {
 		if (el == null || el.tagName === 'BODY') return 'var(--bg)';
-		const bg = el.style.background || el.style.backgroundColor;
-		if (bg) {
-			return bg;
+		const background = el.style.background || el.style.backgroundColor;
+		if (background) {
+			return background;
 		} else {
 			return getParentBg(el.parentElement);
 		}
 	}
 
-	const rawBg = getParentBg(el.value);
+	const rawBg = getParentBg(div.value);
 	const _bg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
 	_bg.setAlpha(0.85);
 	bg.value = _bg.toRgbString();
diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue
index 6b7dfb20e3..c143c2af1f 100644
--- a/packages/frontend/src/components/MkFolder.vue
+++ b/packages/frontend/src/components/MkFolder.vue
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 		</template>
 
-		<div v-if="openedAtLeastOnce" :class="[$style.body, { [$style.bgSame]: bgSame }]" :style="{ maxHeight: maxHeight ? `${maxHeight}px` : null, overflow: maxHeight ? `auto` : null }" :aria-hidden="!opened">
+		<div v-if="openedAtLeastOnce" :class="[$style.body, { [$style.bgSame]: bgSame }]" :style="{ maxHeight: maxHeight ? `${maxHeight}px` : undefined, overflow: maxHeight ? `auto` : undefined }" :aria-hidden="!opened">
 			<Transition
 				:enterActiveClass="defaultStore.state.animation ? $style.transition_toggle_enterActive : ''"
 				:leaveActiveClass="defaultStore.state.animation ? $style.transition_toggle_leaveActive : ''"
@@ -109,7 +109,7 @@ function toggle() {
 
 onMounted(() => {
 	const computedStyle = getComputedStyle(document.documentElement);
-	const parentBg = getBgColor(rootEl.value.parentElement);
+	const parentBg = getBgColor(rootEl.value!.parentElement!);
 	const myBg = computedStyle.getPropertyValue('--panel');
 	bgSame.value = parentBg === myBg;
 });
diff --git a/packages/frontend/src/components/MkFollowButton.vue b/packages/frontend/src/components/MkFollowButton.vue
index 78c4fb3cd2..90a5dcb332 100644
--- a/packages/frontend/src/components/MkFollowButton.vue
+++ b/packages/frontend/src/components/MkFollowButton.vue
@@ -111,17 +111,19 @@ async function onClick() {
 
 				claimAchievement('following1');
 
-				if ($i.followingCount >= 10) {
-					claimAchievement('following10');
-				}
-				if ($i.followingCount >= 50) {
-					claimAchievement('following50');
-				}
-				if ($i.followingCount >= 100) {
-					claimAchievement('following100');
-				}
-				if ($i.followingCount >= 300) {
-					claimAchievement('following300');
+				if ($i) {
+					if ($i.followingCount >= 10) {
+						claimAchievement('following10');
+					}
+					if ($i.followingCount >= 50) {
+						claimAchievement('following50');
+					}
+					if ($i.followingCount >= 100) {
+						claimAchievement('following100');
+					}
+					if ($i.followingCount >= 300) {
+						claimAchievement('following300');
+					}
 				}
 			}
 		}
diff --git a/packages/frontend/src/components/MkForgotPassword.vue b/packages/frontend/src/components/MkForgotPassword.vue
index 9b57688a02..4a0a35b4cf 100644
--- a/packages/frontend/src/components/MkForgotPassword.vue
+++ b/packages/frontend/src/components/MkForgotPassword.vue
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	ref="dialog"
 	:width="370"
 	:height="400"
-	@close="dialog.close()"
+	@close="dialog?.close()"
 	@closed="emit('closed')"
 >
 	<template #header>{{ i18n.ts.forgotPassword }}</template>
@@ -66,6 +66,6 @@ async function onSubmit() {
 		email: email.value,
 	});
 	emit('done');
-	dialog.value.close();
+	dialog.value?.close();
 }
 </script>
diff --git a/packages/frontend/src/components/MkFormDialog.vue b/packages/frontend/src/components/MkFormDialog.vue
index 2095a1dcea..61e23a0a42 100644
--- a/packages/frontend/src/components/MkFormDialog.vue
+++ b/packages/frontend/src/components/MkFormDialog.vue
@@ -40,11 +40,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkSwitch>
 				<MkSelect v-else-if="form[item].type === 'enum'" v-model="values[item]">
 					<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
-					<option v-for="item in form[item].enum" :key="item.value" :value="item.value">{{ item.label }}</option>
+					<option v-for="option in form[item].enum" :key="option.value" :value="option.value">{{ option.label }}</option>
 				</MkSelect>
 				<MkRadios v-else-if="form[item].type === 'radio'" v-model="values[item]">
 					<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
-					<option v-for="item in form[item].options" :key="item.value" :value="item.value">{{ item.label }}</option>
+					<option v-for="option in form[item].options" :key="option.value" :value="option.value">{{ option.label }}</option>
 				</MkRadios>
 				<MkRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].min" :max="form[item].max" :step="form[item].step" :textConverter="form[item].textConverter">
 					<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
@@ -86,6 +86,7 @@ const emit = defineEmits<{
 		canceled?: boolean;
 		result?: any;
 	}): void;
+	(ev: 'closed'): void;
 }>();
 
 const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
@@ -99,13 +100,13 @@ function ok() {
 	emit('done', {
 		result: values,
 	});
-	dialog.value.close();
+	dialog.value?.close();
 }
 
 function cancel() {
 	emit('done', {
 		canceled: true,
 	});
-	dialog.value.close();
+	dialog.value?.close();
 }
 </script>
diff --git a/packages/frontend/src/components/MkGalleryPostPreview.vue b/packages/frontend/src/components/MkGalleryPostPreview.vue
index 316632b1a6..0d8612fe26 100644
--- a/packages/frontend/src/components/MkGalleryPostPreview.vue
+++ b/packages/frontend/src/components/MkGalleryPostPreview.vue
@@ -14,8 +14,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 					leaveActiveClass: $style.transition_toggle_leaveActive,
 					leaveToClass: $style.transition_toggle_leaveTo,
 				}"
-				:src="post.files[0].thumbnailUrl"
-				:hash="post.files[0].blurhash"
+				:src="post.files?.[0]?.thumbnailUrl"
+				:hash="post.files?.[0]?.blurhash"
 				:forceBlurhash="!show"
 			/>
 		</Transition>
diff --git a/packages/frontend/src/components/MkHeatmap.vue b/packages/frontend/src/components/MkHeatmap.vue
index f47b680f83..1913fd4108 100644
--- a/packages/frontend/src/components/MkHeatmap.vue
+++ b/packages/frontend/src/components/MkHeatmap.vue
@@ -27,10 +27,10 @@ const props = defineProps<{
 	src: string;
 }>();
 
-const rootEl = shallowRef<HTMLDivElement>(null);
-const chartEl = shallowRef<HTMLCanvasElement>(null);
+const rootEl = shallowRef<HTMLDivElement | null>(null);
+const chartEl = shallowRef<HTMLCanvasElement | null>(null);
 const now = new Date();
-let chartInstance: Chart = null;
+let chartInstance: Chart | null = null;
 const fetching = ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip({
@@ -38,6 +38,7 @@ const { handler: externalTooltipHandler } = useChartTooltip({
 });
 
 async function renderChart() {
+	if (!rootEl.value || !chartEl.value) return;
 	if (chartInstance) {
 		chartInstance.destroy();
 	}
@@ -56,7 +57,7 @@ async function renderChart() {
 		return new Date(y, m, d - ago);
 	};
 
-	const format = (arr) => {
+	const format = (arr: number[]) => {
 		return arr.map((v, i) => {
 			const dt = getDate(i);
 			const iso = `${dt.getFullYear()}-${(dt.getMonth() + 1).toString().padStart(2, '0')}-${dt.getDate().toString().padStart(2, '0')}`;
@@ -69,7 +70,7 @@ async function renderChart() {
 		});
 	};
 
-	let values;
+	let values: number[] = [];
 
 	if (props.src === 'active-users') {
 		const raw = await misskeyApi('charts/active-users', { limit: chartLimit, span: 'day' });
@@ -106,20 +107,18 @@ async function renderChart() {
 		data: {
 			datasets: [{
 				label: 'Read & Write',
-				data: format(values),
-				pointRadius: 0,
+				data: format(values) as any,
 				borderWidth: 0,
-				borderJoinStyle: 'round',
 				borderRadius: 3,
 				backgroundColor(c) {
-					const value = c.dataset.data[c.dataIndex].v;
+					// @ts-expect-error TS(2339)
+					const value = c.dataset.data[c.dataIndex].v as number;
 					let a = (value - min) / max;
 					if (value !== 0) { // 0でない限りは完全に不可視にはしない
 						a = Math.max(a, 0.05);
 					}
 					return alpha(color, a);
 				},
-				fill: true,
 				width(c) {
 					const a = c.chart.chartArea ?? {};
 					return (a.right - a.left) / weeks - marginEachCell;
@@ -190,11 +189,13 @@ async function renderChart() {
 					enabled: false,
 					callbacks: {
 						title(context) {
-							const v = context[0].dataset.data[context[0].dataIndex];
-							return v.d;
+							// @ts-expect-error TS(2339)
+							return context[0].dataset.data[context[0].dataIndex].d;
 						},
 						label(context) {
 							const v = context.dataset.data[context.dataIndex];
+
+							// @ts-expect-error TS(2339)
 							return ['Active: ' + v.v];
 						},
 					},
diff --git a/packages/frontend/src/components/MkInstanceStats.vue b/packages/frontend/src/components/MkInstanceStats.vue
index 1576089657..50d3ec2779 100644
--- a/packages/frontend/src/components/MkInstanceStats.vue
+++ b/packages/frontend/src/components/MkInstanceStats.vue
@@ -138,7 +138,8 @@ function createDoughnut(chartEl, tooltip, data) {
 				},
 			},
 			onClick: (ev) => {
-				const hit = chartInstance.getElementsAtEventForMode(ev, 'nearest', { intersect: true }, false)[0];
+				if (!ev.native) return;
+				const hit = chartInstance.getElementsAtEventForMode(ev.native, 'nearest', { intersect: true }, false)[0];
 				if (hit && data[hit.index].onClick) {
 					data[hit.index].onClick();
 				}
@@ -164,23 +165,46 @@ function createDoughnut(chartEl, tooltip, data) {
 
 onMounted(() => {
 	misskeyApiGet('federation/stats', { limit: 30 }).then(fedStats => {
-		createDoughnut(subDoughnutEl.value, externalTooltipHandler1, fedStats.topSubInstances.map(x => ({
+		type ChartData = {
+			name: string,
+			color: string | null,
+			value: number,
+			onClick?: () => void,
+		}[];
+
+		const subs: ChartData = fedStats.topSubInstances.map(x => ({
 			name: x.host,
 			color: x.themeColor,
 			value: x.followersCount,
 			onClick: () => {
 				os.pageWindow(`/instance-info/${x.host}`);
 			},
-		})).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowersCount }]));
+		}));
 
-		createDoughnut(pubDoughnutEl.value, externalTooltipHandler2, fedStats.topPubInstances.map(x => ({
+		subs.push({
+			name: '(other)',
+			color: '#80808080',
+			value: fedStats.otherFollowersCount,
+		});
+
+		createDoughnut(subDoughnutEl.value, externalTooltipHandler1, subs);
+
+		const pubs: ChartData = fedStats.topPubInstances.map(x => ({
 			name: x.host,
 			color: x.themeColor,
 			value: x.followingCount,
 			onClick: () => {
 				os.pageWindow(`/instance-info/${x.host}`);
 			},
-		})).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowingCount }]));
+		}));
+
+		pubs.push({
+			name: '(other)',
+			color: '#80808080',
+			value: fedStats.otherFollowingCount,
+		});
+
+		createDoughnut(pubDoughnutEl.value, externalTooltipHandler2, pubs);
 	});
 });
 </script>
diff --git a/packages/frontend/src/components/MkInstanceTicker.vue b/packages/frontend/src/components/MkInstanceTicker.vue
index 3ee2aa7174..b16838dcd5 100644
--- a/packages/frontend/src/components/MkInstanceTicker.vue
+++ b/packages/frontend/src/components/MkInstanceTicker.vue
@@ -30,7 +30,7 @@ const instance = props.instance ?? {
 	themeColor: (document.querySelector('meta[name="theme-color-orig"]') as HTMLMetaElement).content,
 };
 
-const faviconUrl = computed(() => props.instance ? getProxiedImageUrlNullable(props.instance.faviconUrl, 'preview') : getProxiedImageUrlNullable(Instance.iconUrl, 'preview') ?? getProxiedImageUrlNullable(Instance.faviconUrl, 'preview') ?? '/favicon.ico');
+const faviconUrl = computed(() => props.instance ? getProxiedImageUrlNullable(props.instance.faviconUrl, 'preview') : getProxiedImageUrlNullable(Instance.iconUrl, 'preview') ?? '/favicon.ico');
 
 const themeColor = instance.themeColor ?? '#777777';
 
diff --git a/packages/frontend/src/components/MkLaunchPad.vue b/packages/frontend/src/components/MkLaunchPad.vue
index 120ed7a86c..c3ece1ebc2 100644
--- a/packages/frontend/src/components/MkLaunchPad.vue
+++ b/packages/frontend/src/components/MkLaunchPad.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<MkModal ref="modal" v-slot="{ type, maxHeight }" :preferType="preferedModalType" :anchor="anchor" :transparentBg="true" :src="src" @click="modal.close()" @closed="emit('closed')">
+<MkModal ref="modal" v-slot="{ type, maxHeight }" :preferType="preferedModalType" :anchor="anchor" :transparentBg="true" :src="src" @click="modal?.close()" @closed="emit('closed')">
 	<div class="szkkfdyq _popup _shadow" :class="{ asDrawer: type === 'drawer' }" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : '' }">
 		<div class="main">
 			<template v-for="item in items" :key="item.text">
@@ -63,7 +63,7 @@ const items = Object.keys(navbarItemDef).filter(k => !menu.includes(k)).map(k =>
 }));
 
 function close() {
-	modal.value.close();
+	modal.value?.close();
 }
 </script>
 
diff --git a/packages/frontend/src/components/MkMarquee.vue b/packages/frontend/src/components/MkMarquee.vue
index 145b60c8e7..0ea75d4973 100644
--- a/packages/frontend/src/components/MkMarquee.vue
+++ b/packages/frontend/src/components/MkMarquee.vue
@@ -30,6 +30,7 @@ export default {
 		const contentEl = ref<HTMLElement>();
 
 		function calc() {
+			if (!contentEl.value) return;
 			const eachLength = contentEl.value.offsetWidth / props.repeat;
 			const factor = 3000;
 			const duration = props.duration / ((1 / eachLength) * factor);
diff --git a/packages/frontend/src/components/global/MkAcct.vue b/packages/frontend/src/components/global/MkAcct.vue
index 594494f3c8..0171e22c79 100644
--- a/packages/frontend/src/components/global/MkAcct.vue
+++ b/packages/frontend/src/components/global/MkAcct.vue
@@ -21,7 +21,7 @@ import { host as hostRaw } from '@/config.js';
 import { defaultStore } from '@/store.js';
 
 defineProps<{
-	user: Misskey.entities.UserDetailed;
+	user: Misskey.entities.User;
 	detail?: boolean;
 }>();