diff --git a/src/core/util/props.js b/src/core/util/props.js index f81bad37fa1..647813c5393 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -122,13 +122,14 @@ function assertProp ( type = [type] } for (let i = 0; i < type.length && !valid; i++) { - const assertedType = assertType(value, type[i]) + const assertedType = assertType(value, type[i], vm) expectedTypes.push(assertedType.expectedType || '') valid = assertedType.valid } } - if (!valid) { + const haveExpectedTypes = expectedTypes.some(t => t) + if (!valid && haveExpectedTypes) { warn( getInvalidTypeMessage(name, value, expectedTypes), vm @@ -148,7 +149,7 @@ function assertProp ( const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/ -function assertType (value: any, type: Function): { +function assertType (value: any, type: Function, vm: ?Component): { valid: boolean; expectedType: string; } { @@ -166,7 +167,12 @@ function assertType (value: any, type: Function): { } else if (expectedType === 'Array') { valid = Array.isArray(value) } else { - valid = value instanceof type + try { + valid = value instanceof type + } catch (e) { + warn('Invalid prop type: "' + String(type) + '" is not a constructor', vm); + valid = false; + } } return { valid, diff --git a/test/unit/features/options/props.spec.js b/test/unit/features/options/props.spec.js index b2bf482737b..94c03f1ec9f 100644 --- a/test/unit/features/options/props.spec.js +++ b/test/unit/features/options/props.spec.js @@ -553,4 +553,20 @@ describe('Options props', () => { expect(vm.$refs.test.$props.booleanOrString).toBe(true) expect(vm.$refs.test.$props.stringOrBoolean).toBe('') }) + + it('should warn when a prop type is not a constructor', () => { + const vm = new Vue({ + template: '
{{a}}
', + props: { + a: { + type: 'String', + default: 'test' + } + } + }).$mount() + expect( + 'Invalid prop type: "String" is not a constructor' + ).toHaveBeenWarned() + }) + })