fix: 跳过无字段名称配置的类型校验

This commit is contained in:
roymondchen 2026-07-23 16:32:07 +08:00
parent 97e0cac44a
commit 11bf037054
2 changed files with 56 additions and 3 deletions

View File

@ -697,9 +697,13 @@ export const validateTypeMatch = (
return undefined;
}
if (!props.config?.name) {
return undefined;
}
const rawFieldType = 'type' in (props.config || {}) ? props.config.type : '';
if (typeof rawFieldType !== 'string' || !rawFieldType) {
return;
return undefined;
}
// 统一将驼峰形式(如 radioGroup归一化为连字符形式radio-group与内置规则的 key 保持一致

View File

@ -21,6 +21,7 @@ import type { FormState } from '@form/index';
import { getRules } from '@form/utils/form';
import {
clearTypeMatchRules,
createTypeMatchValidator,
deleteTypeMatchRule,
getTypeMatchRule,
registerTypeMatchRule,
@ -51,9 +52,12 @@ const mForm: FormState = {
};
const propsOf = (config: Record<string, any>, model: Record<string, any> = {}) => ({
config,
config: {
name: 'field',
...config,
},
model,
prop: config.name || 'field',
prop: config.name || config.prop || 'field',
});
describe('validateTypeMatch', () => {
@ -64,6 +68,19 @@ describe('validateTypeMatch', () => {
expect(validateTypeMatch([], mForm, propsOf({ type: 'select', multiple: true }))).toBeUndefined();
});
test('config 未配置 name 时跳过校验', () => {
const noNameProps = { config: { type: 'text' }, model: {} };
expect(validateTypeMatch(123, mForm, noNameProps)).toBeUndefined();
expect(validateTypeMatch({ a: 1 }, mForm, { config: { type: 'number' }, model: {} })).toBeUndefined();
expect(
validateTypeMatch('bad', mForm, {
config: { type: 'select', options: [{ text: 'A', value: 'a' }] },
model: {},
}),
).toBeUndefined();
expect(validateTypeMatch(123, mForm, { config: undefined, model: {} })).toBeUndefined();
});
test('0 / false 不视为空值', () => {
expect(validateTypeMatch(0, mForm, propsOf({ type: 'number' }))).toBeUndefined();
expect(validateTypeMatch(false, mForm, propsOf({ type: 'switch' }))).toBeUndefined();
@ -386,6 +403,11 @@ describe('validateTypeMatch', () => {
).toBe('a 类型应为数组\n\n请参考以下示例值["a"]');
});
test('radio-group / checkbox-group 无 options 时跳过校验', () => {
expect(validateTypeMatch('a', mForm, propsOf({ type: 'radio-group' }))).toBeUndefined();
expect(validateTypeMatch('a', mForm, propsOf({ type: 'checkbox-group' }))).toBeUndefined();
});
test('timerange 按 valueFormat 校验', () => {
expect(validateTypeMatch(['12:00:00', '13:00:00'], mForm, propsOf({ type: 'timerange' }))).toBeUndefined();
expect(validateTypeMatch(['bad'], mForm, propsOf({ type: 'timerange' }))).toMatch(
@ -694,3 +716,30 @@ describe('plugin typeMatchRules', () => {
expect(validateTypeMatch('bad', mForm, propsOf({ type: 'install-type' }))).toBe('install error');
});
});
describe('createTypeMatchValidator', () => {
beforeEach(() => {
clearTypeMatchRules();
});
afterEach(() => {
clearTypeMatchRules();
});
test('validateTypeMatch 抛异常时仍执行原始 validator', () => {
registerTypeMatchRule('throw', () => {
throw new Error('boom');
});
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
const originalValidator = vi.fn();
const validator = createTypeMatchValidator(mForm, propsOf({ type: 'throw' }), {
validator: originalValidator,
} as any);
validator({}, 'value', () => {}, {}, {});
expect(originalValidator).toHaveBeenCalled();
expect(errorSpy).toHaveBeenCalled();
errorSpy.mockRestore();
});
});