feat: 将代码迁移至TS严格模式 (#684)

* feat: 将现有代码迁移至TS严格模式 - 禁止隐匿Any的This

* feat: 将代码迁移至TS严格模式 - 启用JS严格模式 和 绑定类型检查

* feat: 移除无用钩子,修改为工具API

* feat: 将代码迁移至TS严格模式 - 启用严格函数类型检查
This commit is contained in:
悠静萝莉 2024-02-18 11:10:42 +08:00 committed by GitHub
parent 944f03a064
commit 0f7096a167
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 48 additions and 84 deletions

View File

@ -8,6 +8,7 @@
"dev:linux": "vite --mode development",
"build:test": "vite build --mode test",
"build": "vue-tsc --noEmit && vite build --mode release",
"build:type": "vue-tsc --noEmit",
"build:site": "vue-tsc --noEmit && vite build --mode site",
"preview": "vite preview",
"lint": "eslint --ext .vue,.js,.jsx,.ts,.tsx ./ --max-warnings 0",

View File

@ -1,34 +0,0 @@
import debounce from 'lodash/debounce';
import { onMounted, onUnmounted } from 'vue';
interface WindowSizeOptions {
immediate?: boolean;
}
interface Fn<T = any, R = T> {
(...arg: T[]): R;
}
export function useWindowSizeFn<T>(fn: Fn<T>, options?: WindowSizeOptions, wait = 150) {
const handleSize: () => void = debounce(fn, wait);
const start = () => {
if (options && options.immediate) {
fn();
}
window.addEventListener('resize', handleSize);
};
const stop = () => {
window.removeEventListener('resize', handleSize);
};
onMounted(() => {
start();
});
onUnmounted(() => {
stop();
});
return [start, stop];
}

View File

@ -6,17 +6,19 @@
</div>
</template>
<script lang="ts" setup>
import { useWindowSize } from '@vueuse/core';
import debounce from 'lodash/debounce';
import { computed, CSSProperties, ref, unref, watch } from 'vue';
import { prefix } from '@/config/global';
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn';
import { useSettingStore } from '@/store';
defineProps({
frameSrc: String,
});
const { width, height } = useWindowSize();
const loading = ref(true);
const heightRef = ref(window.innerHeight);
const frameRef = ref<HTMLFrameElement>();
@ -69,8 +71,8 @@ function hideLoading() {
calcHeight();
}
useWindowSizeFn(calcHeight, { immediate: true });
//
watch([width, height], debounce(calcHeight, 250));
watch(
[() => settingStore.showFooter, () => settingStore.isUseTabsRouter, () => settingStore.showBreadcrumb],
debounce(calcHeight, 250),

View File

@ -38,9 +38,13 @@
<translate-icon />
</t-button>
<t-dropdown-menu>
<t-dropdown-item v-for="(lang, index) in langList" :key="index" :value="lang.value" @click="changeLang">{{
lang.content
}}</t-dropdown-item></t-dropdown-menu
<t-dropdown-item
v-for="(lang, index) in langList"
:key="index"
:value="lang.value"
@click="(options) => changeLang(options.value as string)"
>{{ lang.content }}</t-dropdown-item
></t-dropdown-menu
>
</t-dropdown>
<t-dropdown :min-column-width="120" trigger="click">
@ -85,7 +89,7 @@ import { langList } from '@/locales/index';
import { useLocale } from '@/locales/useLocale';
import { getActive } from '@/router';
import { useSettingStore, useUserStore } from '@/store';
import type { MenuRoute } from '@/types/interface';
import type { MenuRoute, ModeType } from '@/types/interface';
import MenuContent from './MenuContent.vue';
import Notice from './Notice.vue';
@ -147,11 +151,11 @@ const menuCls = computed(() => {
},
];
});
const menuTheme = computed(() => props.theme as 'light' | 'dark');
const menuTheme = computed(() => props.theme as ModeType);
//
const { changeLocale } = useLocale();
const changeLang = ({ value: lang }: { value: string }) => {
const changeLang = (lang: string) => {
changeLocale(lang);
};

View File

@ -7,7 +7,7 @@
:class="`${prefix}-layout-tabs-nav`"
:value="$route.path"
:style="{ position: 'sticky', top: 0, width: '100%' }"
@change="handleChangeCurrentTab"
@change="(value) => handleChangeCurrentTab(value as string)"
@remove="handleRemove"
@drag-sort="handleDragend"
>

View File

@ -26,7 +26,7 @@ import AssetLogo from '@/assets/assets-t-logo.svg?component';
import { prefix } from '@/config/global';
import { getActive, getRoutesExpanded } from '@/router';
import { useSettingStore } from '@/store';
import type { MenuRoute } from '@/types/interface';
import type { MenuRoute, ModeType } from '@/types/interface';
import pgk from '../../../package.json';
import MenuContent from './MenuContent.vue';
@ -55,7 +55,7 @@ const props = defineProps({
default: '64px',
},
theme: {
type: String as PropType<'light' | 'dark'>,
type: String as PropType<ModeType>,
default: 'light',
},
isCompact: {

View File

@ -14,7 +14,7 @@
theme="primary"
mode="date"
:default-value="LAST_7_DAYS"
@change="onCurrencyChange"
@change="(value) => onCurrencyChange(value as string[])"
/>
</div>
</template>

View File

@ -14,7 +14,7 @@
theme="primary"
mode="date"
:default-value="LAST_7_DAYS"
@change="onStokeDataChange"
@change="(value) => onStokeDataChange(value as string[])"
/>
</template>
<div id="stokeContainer" style="width: 100%; height: 351px" class="dashboard-chart-container"></div>

View File

@ -26,7 +26,7 @@
theme="primary"
mode="date"
style="width: 248px"
@change="onMaterialChange"
@change="(value) => onMaterialChange(value as string[])"
/>
</template>
<div id="lineContainer" style="width: 100%; height: 416px" />

View File

@ -31,7 +31,7 @@
:header-affixed-top="headerAffixedTop"
@page-change="rehandlePageChange"
@change="rehandleChange"
@select-change="rehandleSelectChange"
@select-change="(value) => rehandleSelectChange(value as number[])"
>
<template #status="{ row }">
<t-tag v-if="row.status === CONTRACT_STATUS.FAIL" theme="danger" variant="light">

View File

@ -74,7 +74,7 @@ const formVisible = ref(false);
const formData = ref({ ...INITIAL_DATA });
const textareaValue = ref('');
const onSubmit = ({ validateResult, firstError }: SubmitContext<FormData>) => {
const onSubmit = ({ validateResult, firstError }: SubmitContext) => {
if (!firstError) {
MessagePlugin.success('提交成功');
formVisible.value = false;

View File

@ -2,15 +2,16 @@ import keys from 'lodash/keys';
import { defineStore } from 'pinia';
import { Color } from 'tvision-color';
import { DARK_CHART_COLORS, LIGHT_CHART_COLORS } from '@/config/color';
import { DARK_CHART_COLORS, LIGHT_CHART_COLORS, TColorSeries } from '@/config/color';
import STYLE_CONFIG from '@/config/style';
import { store } from '@/store';
import { ModeType } from '@/types/interface';
import { generateColorMap, insertThemeStylesheet } from '@/utils/color';
const state = {
const state: Record<string, any> = {
...STYLE_CONFIG,
showSettingPanel: false,
colorList: {},
colorList: {} as TColorSeries,
chartColors: LIGHT_CHART_COLORS,
};
@ -23,7 +24,7 @@ export const useSettingStore = defineStore('setting', {
showSidebar: (state) => state.layout !== 'top',
showSidebarLogo: (state) => state.layout === 'side',
showHeaderLogo: (state) => state.layout !== 'side',
displayMode: (state): 'dark' | 'light' => {
displayMode: (state): ModeType => {
if (state.mode === 'auto') {
const media = window.matchMedia('(prefers-color-scheme:dark)');
if (media.matches) {
@ -31,14 +32,14 @@ export const useSettingStore = defineStore('setting', {
}
return 'light';
}
return state.mode as 'dark' | 'light';
return state.mode as ModeType;
},
displaySideMode: (state): 'dark' | 'light' => {
return state.sideMode as 'dark' | 'light';
displaySideMode: (state): ModeType => {
return state.sideMode as ModeType;
},
},
actions: {
async changeMode(mode: 'dark' | 'light' | 'auto') {
async changeMode(mode: ModeType | 'auto') {
let theme = mode;
if (mode === 'auto') {
@ -50,7 +51,7 @@ export const useSettingStore = defineStore('setting', {
this.chartColors = isDarkMode ? DARK_CHART_COLORS : LIGHT_CHART_COLORS;
},
async changeSideMode(mode: 'dark' | 'light') {
async changeSideMode(mode: ModeType) {
const isDarkMode = mode === 'dark';
document.documentElement.setAttribute('side-mode', isDarkMode ? 'dark' : '');
@ -75,23 +76,23 @@ export const useSettingStore = defineStore('setting', {
step: 10,
remainInput: false, // 是否保留输入 不保留会矫正不合适的主题色
});
colorMap = generateColorMap(brandTheme, newPalette, mode as 'light' | 'dark', brandColorIndex);
colorMap = generateColorMap(brandTheme, newPalette, mode, brandColorIndex);
this.colorList[colorKey] = colorMap;
}
// TODO 需要解决不停切换时有反复插入 style 的问题
insertThemeStylesheet(brandTheme, colorMap, mode as 'light' | 'dark');
insertThemeStylesheet(brandTheme, colorMap, mode);
document.documentElement.setAttribute('theme-color', brandTheme);
},
updateConfig(payload: Partial<TState>) {
for (const key in payload) {
if (payload[key as TStateKey] !== undefined) {
this[key] = payload[key as TStateKey];
this[key as TStateKey] = payload[key as TStateKey];
}
if (key === 'mode') {
this.changeMode(payload[key]);
this.changeMode(payload[key] as ModeType);
}
if (key === 'sideMode') {
this.changeSideMode(payload[key]);
this.changeSideMode(payload[key] as ModeType);
}
if (key === 'brandTheme') {
this.changeBrandTheme(payload[key]);

View File

@ -1,8 +1,6 @@
import type { TabValue } from 'tdesign-vue-next';
import { LocationQueryRaw, RouteRecordName } from 'vue-router';
import STYLE_CONFIG from '@/config/style';
export interface RouteMeta {
title?: string | Record<string, string>;
icon?: string;
@ -32,14 +30,6 @@ export interface MenuRoute {
export type ModeType = 'dark' | 'light';
export type SettingType = typeof STYLE_CONFIG;
export type ClassName = { [className: string]: any } | ClassName[] | string;
export type CommonObjType = {
[key: string]: string | number;
};
export interface UserInfo {
name: string;
roles: string[];

View File

@ -3,6 +3,7 @@ import trim from 'lodash/trim';
import { Color } from 'tvision-color';
import { TColorToken } from '@/config/color';
import { ModeType } from '@/types/interface';
/**
*
@ -58,12 +59,7 @@ export function changeChartsTheme(chartsList: echarts.EChartsType[]): void {
/**
*
*/
export function generateColorMap(
theme: string,
colorPalette: Array<string>,
mode: 'light' | 'dark',
brandColorIdx: number,
) {
export function generateColorMap(theme: string, colorPalette: Array<string>, mode: ModeType, brandColorIdx: number) {
const isDarkMode = mode === 'dark';
if (isDarkMode) {
@ -76,7 +72,7 @@ export function generateColorMap(
colorPalette[0] = `${colorPalette[brandColorIdx]}20`;
}
const colorMap = {
const colorMap: TColorToken = {
'--td-brand-color': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-1': colorPalette[0], // light
'--td-brand-color-2': colorPalette[1], // focus
@ -95,7 +91,7 @@ export function generateColorMap(
/**
*
*/
export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: 'light' | 'dark') {
export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: ModeType) {
const isDarkMode = mode === 'dark';
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;

View File

@ -16,7 +16,11 @@
"paths": {
"@/*": ["src/*"]
},
"noImplicitAny": true
"noImplicitAny": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"alwaysStrict": true,
},
"include": [
"**/*.ts",