diff --git a/packages/runtime-core/__tests__/componentProps.spec.ts b/packages/runtime-core/__tests__/componentProps.spec.ts index ac1dc13dfcc..863b12d0699 100644 --- a/packages/runtime-core/__tests__/componentProps.spec.ts +++ b/packages/runtime-core/__tests__/componentProps.spec.ts @@ -556,4 +556,21 @@ describe('component props', () => { await nextTick() expect(serializeInner(root)).toBe(`foo`) }) + + test('support null in required + multiple-type declarations', () => { + const Comp = { + props: { + foo: { type: [Function, null], required: true } + }, + render() {} + } + const root = nodeOps.createElement('div') + expect(() => { + render(h(Comp, { foo: () => {} }), root) + }).not.toThrow() + + expect(() => { + render(h(Comp, { foo: null }), root) + }).not.toThrow() + }) }) diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index c4ab05dd021..6cc6746a57e 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -529,7 +529,7 @@ function validatePropName(key: string) { // so that it works across vms / iframes. function getType(ctor: Prop): string { const match = ctor && ctor.toString().match(/^\s*function (\w+)/) - return match ? match[1] : '' + return match ? match[1] : ctor === null ? 'null' : '' } function isSameType(a: Prop, b: Prop): boolean { @@ -637,6 +637,8 @@ function assertType(value: unknown, type: PropConstructor): AssertionResult { valid = isObject(value) } else if (expectedType === 'Array') { valid = isArray(value) + } else if (expectedType === 'null') { + valid = value === null } else { valid = value instanceof type } @@ -656,7 +658,7 @@ function getInvalidTypeMessage( ): string { let message = `Invalid prop: type check failed for prop "${name}".` + - ` Expected ${expectedTypes.map(capitalize).join(', ')}` + ` Expected ${expectedTypes.map(capitalize).join(' | ')}` const expectedType = expectedTypes[0] const receivedType = toRawType(value) const expectedValue = styleValue(value, expectedType)