diff --git a/packages/components/date-picker/hooks/useRange.tsx b/packages/components/date-picker/hooks/useRange.tsx index aa9f2b6bec..660268b21c 100644 --- a/packages/components/date-picker/hooks/useRange.tsx +++ b/packages/components/date-picker/hooks/useRange.tsx @@ -35,7 +35,7 @@ export default function useRange(props: TdDateRangePickerProps) { const popupVisible = ref(false); const isHoverCell = ref(false); - const activeIndex = ref(0); // 确定当前选中的输入框序号 + const activeIndex = ref<0 | 1>(0); // 确定当前选中的输入框序号 const inputValue = ref(formatDate(props.value, { format: formatRef.value.format })); // 未真正选中前可能不断变更输入框的内容 const isReadOnly = useReadonly(); @@ -128,6 +128,8 @@ export default function useRange(props: TdDateRangePickerProps) { // 这里劫持了进一步向 popup 传递的 onVisibleChange 事件,为了保证可以在 Datepicker 中使用 popupProps.onVisibleChange,故此处理 props.popupProps?.onVisibleChange?.(visible, context); + // TODO + // @ts-ignore types only declare onVisibleChange,but not declare on-visible-change props.popupProps?.['on-visible-change']?.(visible, context); // 输入框点击不关闭面板 diff --git a/packages/components/date-picker/hooks/useSingle.tsx b/packages/components/date-picker/hooks/useSingle.tsx index 036e1eb0e2..0393e9587f 100644 --- a/packages/components/date-picker/hooks/useSingle.tsx +++ b/packages/components/date-picker/hooks/useSingle.tsx @@ -127,6 +127,8 @@ export default function useSingle(props: TdDatePickerProps) { if (disabled.value) return; // 这里劫持了进一步向 popup 传递的 onVisibleChange 事件,为了保证可以在 Datepicker 中使用 popupProps.onVisibleChange,故此处理 props.popupProps?.onVisibleChange?.(visible, context); + // TODO + // @ts-ignore types only declare onVisibleChange,but not declare on-visible-change props.popupProps?.['on-visible-change']?.(visible, context); // 输入框点击不关闭面板 if (context.trigger === 'trigger-element-click') { diff --git a/packages/components/dialog/dialog.tsx b/packages/components/dialog/dialog.tsx index 12b9843f23..69e843dbd5 100644 --- a/packages/components/dialog/dialog.tsx +++ b/packages/components/dialog/dialog.tsx @@ -296,6 +296,7 @@ export default defineComponent({ const hasEventOn = (name: string) => { // _events 因没有被暴露在vue实例接口中,只能把这个规则注释掉 // eslint-disable-next-line dot-notation + // @ts-ignore const eventFuncs = this['_events']?.[name]; return !!eventFuncs?.length; }; diff --git a/packages/components/dialog/hooks.tsx b/packages/components/dialog/hooks.tsx index 012f72f5a9..fb98c3257d 100644 --- a/packages/components/dialog/hooks.tsx +++ b/packages/components/dialog/hooks.tsx @@ -7,6 +7,7 @@ import TButton, { ButtonProps } from '../button'; import { PopconfirmConfig, DialogConfig, DrawerConfig } from '../config-provider'; import type { ClassName } from '../common'; import type { TdDialogProps } from './type'; +import { getPropertyValFromObj } from '../../utils/general'; export interface MixinsConfirmBtn { theme?: MixinsThemeType; @@ -38,8 +39,10 @@ export function useAction(action: BtnAction) { // 全局配置属性综合 const getDefaultConfirmBtnProps = (options: MixinsConfirmBtn): ButtonProps => { const { globalConfirm, theme, globalConfirmBtnTheme } = options; - const defaultTheme = omit(globalConfirmBtnTheme, ['info'])?.[theme] || 'primary'; + const defaultTheme = getPropertyValFromObj(omit(globalConfirmBtnTheme, ['info']), theme) || 'primary'; let props: ButtonProps = { + // @ts-ignore + // TODO: 这里的类型是有问题的,出在 globalConfirmBtnTheme 上 theme: defaultTheme, size: options.size, onClick: (e) => { diff --git a/packages/components/form/form-item.tsx b/packages/components/form/form-item.tsx index bae475df04..cb2492af67 100644 --- a/packages/components/form/form-item.tsx +++ b/packages/components/form/form-item.tsx @@ -252,10 +252,13 @@ export default defineComponent({ .filter((item) => item.result !== true) .map((item: ErrorListType) => { Object.keys(item).forEach((key) => { + // @ts-ignore if (!item.message && errorMessages.value[key]) { const name = isString(props.label) ? props.label : props.name; + // @ts-ignore item.message = template(errorMessages.value[key], { name, + // @ts-ignore validate: item[key], }); } diff --git a/packages/components/form/form.tsx b/packages/components/form/form.tsx index b2383b9124..c74e7b6aec 100644 --- a/packages/components/form/form.tsx +++ b/packages/components/form/form.tsx @@ -94,7 +94,7 @@ export default defineComponent({ return fields.indexOf(`${name}`) !== -1; }; const formatValidateResult = (validateResultList: FormItemValidateResult[]) => { - const result = validateResultList.reduce((r, err) => Object.assign(r || {}, err), {}); + const result: Record = validateResultList.reduce((r, err) => Object.assign(r || {}, err), {}); Object.keys(result).forEach((key) => { if (result[key] === true) { delete result[key]; @@ -172,6 +172,8 @@ export default defineComponent({ if (!keys.length) return; const list = children.value .filter((child) => isFunction(child.setValidateMessage) && keys.includes(`${child.name}`)) + // @ts-ignore + // TODO: 😭 .map((child) => child.setValidateMessage(validateMessage[child.name])); Promise.all(list); }; diff --git a/packages/components/grid/common.ts b/packages/components/grid/common.ts index 87ae34d00f..5fbd46cc31 100644 --- a/packages/components/grid/common.ts +++ b/packages/components/grid/common.ts @@ -4,7 +4,7 @@ import { isNumber } from 'lodash-es'; import { isObject } from 'lodash-es'; import { isArray } from 'lodash-es'; -import { TdColProps, TdRowProps } from './type'; +import { GutterObject, TdColProps, TdRowProps } from './type'; import { calcSize } from '../../utils/responsive'; import { useListener } from '../hooks/useListener'; import { isServer } from '../utils/dom'; @@ -52,7 +52,8 @@ export function getRowClasses(name: string, props: TdRowProps) { * @param currentSize * @returns */ -export function calcRowStyle(gutter: TdRowProps['gutter'], currentSize: string) { +// TODO: 看代码,已经没有用到了,是不是可以删除了 +export function calcRowStyle(gutter: TdRowProps['gutter'], currentSize: keyof GutterObject) { const rowStyle = {}; const getMarginStyle = (gutter: number) => Object.assign(rowStyle, { @@ -80,6 +81,7 @@ export function calcRowStyle(gutter: TdRowProps['gutter'], currentSize: string) } if (isObject(gutter[0]) && !isUndefined(gutter[0][currentSize])) { + const a = gutter[0]; getMarginStyle(gutter[0][currentSize]); } @@ -89,11 +91,17 @@ export function calcRowStyle(gutter: TdRowProps['gutter'], currentSize: string) } }, isObject: (gutter: TdRowProps['gutter']) => { + // TODO: 好吧,这里明显就不对 + // @ts-ignore if (isObject(gutter) && gutter[currentSize]) { if (isArray(gutter) && gutter.length) { + // @ts-ignore + // TODO: 你看,这里是数组吧,但又来 currentSize getMarginStyle(gutter[currentSize][0]); + // @ts-ignore getRowGapStyle(gutter[currentSize][1]); } else { + // @ts-ignore getMarginStyle(gutter[currentSize]); } } @@ -101,12 +109,12 @@ export function calcRowStyle(gutter: TdRowProps['gutter'], currentSize: string) }; Object.keys(strategyMap).forEach((item) => { + // @ts-ignore strategyMap[item](gutter); }); return rowStyle; } - /** * 解析Flex * @param flex @@ -129,7 +137,7 @@ export function parseFlex(flex: TdColProps['flex']): string { * @param currentSize * @returns */ -export function calcColPadding(gutter: TdRowProps['gutter'], currentSize: string) { +export function calcColPadding(gutter: TdRowProps['gutter'], currentSize: keyof GutterObject) { const paddingObj = {}; const getPaddingStyle = (gutter: number) => Object.assign(paddingObj, { @@ -154,13 +162,14 @@ export function calcColPadding(gutter: TdRowProps['gutter'], currentSize: string } }, isObject: (gutter: TdRowProps['gutter']) => { - if (isObject(gutter) && gutter[currentSize]) { + // TODO: 你看,这里就不对的 isObject 在乱用 + if (isObject(gutter) && !isArray(gutter) && gutter[currentSize]) { getPaddingStyle(gutter[currentSize]); } }, }; - Object.keys(strategyMap).forEach((item) => { + Object.keys(strategyMap).forEach((item: keyof typeof strategyMap) => { strategyMap[item](gutter); }); @@ -174,7 +183,7 @@ export function calcColPadding(gutter: TdRowProps['gutter'], currentSize: string */ export function getColClasses(name: string, props: TdColProps) { const { span, order, offset, push, pull } = props; - const allSizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl']; + const allSizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'] as const; const ColSizeClasses = allSizes.reduce((acc, currSize) => { const sizeProp = props[currSize]; diff --git a/packages/components/grid/row.tsx b/packages/components/grid/row.tsx index 1cad22612f..5c1552e950 100644 --- a/packages/components/grid/row.tsx +++ b/packages/components/grid/row.tsx @@ -25,7 +25,7 @@ export default defineComponent({ const COMPONENT_NAME = usePrefixClass('row'); const rowClasses = computed(() => getRowClasses(COMPONENT_NAME.value, props)); - const rowStyle = computed(() => calcRowStyle(props.gutter, size.value)); + const rowStyle = computed(() => (props.gutter, size.value)); return () => { const { tag: TAG } = props; diff --git a/packages/components/hooks/icon.tsx b/packages/components/hooks/icon.tsx index df14988af5..5a4fc9adba 100644 --- a/packages/components/hooks/icon.tsx +++ b/packages/components/hooks/icon.tsx @@ -14,7 +14,7 @@ export function useIcon() { let iconContent; // 传入的是渲染函数 if (isFunction(instance.props[iconType])) { - iconContent = (instance.props as Object)[iconType](h); + iconContent = instance.props[iconType](h); } else if (instance.slots[iconType]) { // 插槽slot iconContent = instance.slots[iconType] && instance.slots[iconType](null)[0]; diff --git a/packages/components/hooks/useGlobalIcon.ts b/packages/components/hooks/useGlobalIcon.ts index cc42d83ae7..5c5ecaef27 100644 --- a/packages/components/hooks/useGlobalIcon.ts +++ b/packages/components/hooks/useGlobalIcon.ts @@ -2,12 +2,12 @@ import { useConfig } from './useConfig'; import { IconConfig } from '../config-provider/type'; // 从 globalConfig 获取 icon 配置用于覆盖组件内置 icon -export function useGlobalIcon(tdIcon: Object) { +export function useGlobalIcon(tdIcon: object) { const { globalConfig } = useConfig('icon'); const resultIcon: IconConfig = {}; - Object.keys(tdIcon).forEach((key) => { + Object.keys(tdIcon).forEach((key: keyof typeof tdIcon) => { resultIcon[key] = globalConfig.value?.[key] || tdIcon[key]; }); diff --git a/packages/components/input/input.tsx b/packages/components/input/input.tsx index 38ef50a089..279c007559 100644 --- a/packages/components/input/input.tsx +++ b/packages/components/input/input.tsx @@ -71,8 +71,8 @@ export default defineComponent({ const inputEventHandler = useInputEventHandler(props, isHover); const tPlaceholder = computed(() => props.placeholder ?? globalConfig.value.placeholder); - const inputAttrs = computed(() => - getValidAttrs({ + const inputAttrs = computed(() => { + const value = { autofocus: props.autofocus, disabled: disabled.value, readonly: readonly.value, @@ -80,13 +80,14 @@ export default defineComponent({ name: props.name || undefined, type: renderType.value, autocomplete: props.autocomplete ?? (globalConfig.value.autocomplete || undefined), - unselectable: readonly.value ? 'on' : undefined, + unselectable: readonly.value ? 'on' : 'off', spellcheck: props.spellCheck, // 不要传给 input 原生元素 maxlength,浏览器默认行为会按照 unicode 进行限制,与 maxLength API 违背 // https://github.com/Tencent/tdesign-vue-next/issues/4413 // 参见: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/maxlength,提到了字符串长度的计算方法,就是 str.length - }), - ); + } as const; + return getValidAttrs(value); + }); const wrapClasses = computed(() => [ INPUT_WRAP_CLASS.value, diff --git a/packages/components/loading/directive.ts b/packages/components/loading/directive.ts index 0affe55a93..1659d51f92 100644 --- a/packages/components/loading/directive.ts +++ b/packages/components/loading/directive.ts @@ -17,6 +17,8 @@ const createInstance = (el: HTMLElement, binding: DirectiveBinding) => { if (isObject(binding.value)) { mapKeys(binding.value, (value, key) => { + // @ts-ignore + // TODO: 😭 options[key] = value; }); } diff --git a/packages/utils/general.ts b/packages/utils/general.ts index 1eb27ea957..f03a0b3115 100644 --- a/packages/utils/general.ts +++ b/packages/utils/general.ts @@ -1,3 +1,5 @@ +import { isFunction, isObject } from 'lodash-es'; + const hasOwnProperty = Object.prototype.hasOwnProperty; export const hasOwn = (val: T, key: string | symbol | number): key is keyof T => @@ -11,16 +13,7 @@ export const getPropertyValFromObj = ( const objectToString: typeof Object.prototype.toString = Object.prototype.toString; const toTypeString = (value: unknown): string => objectToString.call(value); -export const isArray: typeof Array.isArray = Array.isArray; -export const isMap = (val: unknown): val is Map => toTypeString(val) === '[object Map]'; -export const isSet = (val: unknown): val is Set => toTypeString(val) === '[object Set]'; -export const isDate = (val: unknown): val is Date => toTypeString(val) === '[object Date]'; -export const isRegExp = (val: unknown): val is RegExp => toTypeString(val) === '[object RegExp]'; -export const isFunction = (val: unknown): val is Function => typeof val === 'function'; -export const isString = (val: unknown): val is string => typeof val === 'string'; -export const isSymbol = (val: unknown): val is symbol => typeof val === 'symbol'; -export const isPlainObject = (val: unknown): val is object => toTypeString(val) === '[object Object]'; -export const isObject = (val: unknown): val is object => val !== null && typeof val === 'object'; +export const isPlainObject = (val: unknown): val is T => toTypeString(val) === '[object Object]'; export const isPromise = (val: unknown): val is Promise => { return (isObject(val) || isFunction(val)) && isFunction((val as any).then) && isFunction((val as any).catch); };