Repository: vuejs/vue
Pull request: fix(warn): better message with no constructors props

Closes #9224

<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [ ] Bugfix
- [ ] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [x] Other, please describe: Error Handling

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [x] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**
### Proof
**Before**

![screen shot 2018-12-22 at 1 36 46 pm](https://user-images.githubusercontent.com/18662248/50373943-af205d80-05ee-11e9-930d-ae1e798b03fc.png)


**After**

![screen shot 2018-12-22 at 1 37 43 pm](https://user-images.githubusercontent.com/18662248/50373959-045c6f00-05ef-11e9-8eb8-5715e099cdde.png)

Changed files:
filename: src/core/util/props.js
patch: @@ -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,

filename: test/unit/features/options/props.spec.js
patch: @@ -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: '<div>{{a}}</div>',
+      props: {
+        a: {
+          type: 'String',
+          default: 'test'
+        }
+      }
+    }).$mount()
+    expect(
+      'Invalid prop type: "String" is not a constructor'
+    ).toHaveBeenWarned()
+  })
+
 })