@@ -14,6 +14,7 @@ import {
1414 extend ,
1515 hasOwn ,
1616 camelize ,
17+ toRawType ,
1718 capitalize ,
1819 isBuiltInTag ,
1920 isPlainObject
@@ -155,11 +156,19 @@ LIFECYCLE_HOOKS.forEach(hook => {
155156 * a three-way merge between constructor options, instance
156157 * options and parent options.
157158 */
158- function mergeAssets ( parentVal : ?Object , childVal : ?Object ) : Object {
159+ function mergeAssets (
160+ parentVal : ?Object ,
161+ childVal : ?Object ,
162+ vm ? : Component ,
163+ key : string
164+ ) : Object {
159165 const res = Object . create ( parentVal || null )
160- return childVal
161- ? extend ( res , childVal )
162- : res
166+ if ( childVal ) {
167+ process . env . NODE_ENV !== 'production' && assertObjectType ( key , childVal , vm )
168+ return extend ( res , childVal )
169+ } else {
170+ return res
171+ }
163172}
164173
165174ASSET_TYPES . forEach ( function ( type ) {
@@ -172,12 +181,20 @@ ASSET_TYPES.forEach(function (type) {
172181 * Watchers hashes should not overwrite one
173182 * another, so we merge them as arrays.
174183 */
175- strats . watch = function ( parentVal : ?Object , childVal : ?Object ) : ?Object {
184+ strats . watch = function (
185+ parentVal : ?Object ,
186+ childVal : ?Object ,
187+ vm ?: Component ,
188+ key : string
189+ ) : ?Object {
176190 // work around Firefox's Object.prototype.watch...
177191 if ( parentVal === nativeWatch ) parentVal = undefined
178192 if ( childVal === nativeWatch ) childVal = undefined
179193 /* istanbul ignore if */
180194 if ( ! childVal ) return Object . create ( parentVal || null )
195+ if ( process . env . NODE_ENV !== 'production' ) {
196+ assertObjectType ( key , childVal , vm )
197+ }
181198 if ( ! parentVal ) return childVal
182199 const ret = { }
183200 extend ( ret , parentVal )
@@ -200,7 +217,15 @@ strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object {
200217strats . props =
201218strats . methods =
202219strats . inject =
203- strats . computed = function ( parentVal : ?Object , childVal : ?Object ) : ?Object {
220+ strats . computed = function (
221+ parentVal : ?Object ,
222+ childVal : ?Object ,
223+ vm ?: Component ,
224+ key : string
225+ ) : ?Object {
226+ if ( childVal && process . env . NODE_ENV !== 'production' ) {
227+ assertObjectType ( key , childVal , vm )
228+ }
204229 if ( ! parentVal ) return childVal
205230 const ret = Object . create ( null )
206231 extend ( ret , parentVal )
@@ -237,7 +262,7 @@ function checkComponents (options: Object) {
237262 * Ensure all props option syntax are normalized into the
238263 * Object-based format.
239264 */
240- function normalizeProps ( options : Object ) {
265+ function normalizeProps ( options : Object , vm : ? Component ) {
241266 const props = options . props
242267 if ( ! props ) return
243268 const res = { }
@@ -261,14 +286,20 @@ function normalizeProps (options: Object) {
261286 ? val
262287 : { type : val }
263288 }
289+ } else if ( process . env . NODE_ENV !== 'production' && props ) {
290+ warn (
291+ `Invalid value for option "props": expected an Array or an Object, ` +
292+ `but got ${ toRawType ( props ) } .` ,
293+ vm
294+ )
264295 }
265296 options . props = res
266297}
267298
268299/**
269300 * Normalize all injections into Object-based format
270301 */
271- function normalizeInject ( options : Object ) {
302+ function normalizeInject ( options : Object , vm : ? Component ) {
272303 const inject = options . inject
273304 const normalized = options . inject = { }
274305 if ( Array . isArray ( inject ) ) {
@@ -282,6 +313,12 @@ function normalizeInject (options: Object) {
282313 ? extend ( { from : key } , val )
283314 : { from : val }
284315 }
316+ } else if ( process . env . NODE_ENV !== 'production' && inject ) {
317+ warn (
318+ `Invalid value for option "inject": expected an Array or an Object, ` +
319+ `but got ${ toRawType ( inject ) } .` ,
320+ vm
321+ )
285322 }
286323}
287324
@@ -300,6 +337,16 @@ function normalizeDirectives (options: Object) {
300337 }
301338}
302339
340+ function assertObjectType ( name : string , value : any , vm : ?Component ) {
341+ if ( ! isPlainObject ( value ) ) {
342+ warn (
343+ `Invalid value for option "${ name } ": expected an Object, ` +
344+ `but got ${ toRawType ( value ) } .` ,
345+ vm
346+ )
347+ }
348+ }
349+
303350/**
304351 * Merge two option objects into a new one.
305352 * Core utility used in both instantiation and inheritance.
@@ -317,8 +364,8 @@ export function mergeOptions (
317364 child = child . options
318365 }
319366
320- normalizeProps ( child )
321- normalizeInject ( child )
367+ normalizeProps ( child , vm )
368+ normalizeInject ( child , vm )
322369 normalizeDirectives ( child )
323370 const extendsFrom = child . extends
324371 if ( extendsFrom ) {
0 commit comments