Repository: vuejs/vue
Pull request: improve data set/delete API

I improved `Vue.set/Vue.delete (vm.$set/vm.$delete)` flowtype interface, and also I refactored these API.
In the API of `Vue.set `(vm.$set)`, docs said:

> Returns: the set value.

https://vuejs.org/v2/api/#Vue-set


Changed files:
filename: flow/component.js
patch: @@ -35,8 +35,8 @@ declare interface Component {
   $mount: (el?: Element | string, hydrating?: boolean) => Component;
   $forceUpdate: () => void;
   $destroy: () => void;
-  $set: (obj: Array<mixed> | Object, key: mixed, val: mixed) => void;
-  $delete: (obj: Object, key: string) => void;
+  $set: <T>(target: Object | Array<T>, key: string | number, val: T) => T;
+  $delete: <T>(target: Object | Array<T>, key: string | number) => void;
   $watch: (expOrFn: string | Function, cb: Function, options?: Object) => Function;
   $on: (event: string | Array<string>, fn: Function) => Component;
   $once: (event: string, fn: Function) => Component;

filename: flow/global-api.js
patch: @@ -5,8 +5,8 @@ declare interface GlobalAPI {
   util: Object;
 
   extend: (options: Object) => Function;
-  set: (obj: Object, key: string, value: any) => void;
-  delete: (obj: Object, key: string) => void;
+  set: <T>(target: Object | Array<T>, key: string | number, value: T) => T;
+  delete: <T>(target: Object| Array<T>, key: string | number) => void;
   nextTick: (fn: Function, context?: Object) => void;
   use: (plugin: Function | Object) => void;
   mixin: (mixin: Object) => void;

filename: src/core/observer/index.js
patch: @@ -188,27 +188,27 @@ export function defineReactive (
  * triggers change notification if the property doesn't
  * already exist.
  */
-export function set (obj: Array<any> | Object, key: any, val: any) {
-  if (Array.isArray(obj)) {
-    obj.length = Math.max(obj.length, key)
-    obj.splice(key, 1, val)
+export function set (target: Array<any> | Object, key: any, val: any): any {
+  if (Array.isArray(target)) {
+    target.length = Math.max(target.length, key)
+    target.splice(key, 1, val)
     return val
   }
-  if (hasOwn(obj, key)) {
-    obj[key] = val
-    return
+  if (hasOwn(target, key)) {
+    target[key] = val
+    return val
   }
-  const ob = obj.__ob__
-  if (obj._isVue || (ob && ob.vmCount)) {
+  const ob = target.__ob__
+  if (target._isVue || (ob && ob.vmCount)) {
     process.env.NODE_ENV !== 'production' && warn(
       'Avoid adding reactive properties to a Vue instance or its root $data ' +
       'at runtime - declare it upfront in the data option.'
     )
-    return
+    return val
   }
   if (!ob) {
-    obj[key] = val
-    return
+    target[key] = val
+    return val
   }
   defineReactive(ob.value, key, val)
   ob.dep.notify()
@@ -218,23 +218,23 @@ export function set (obj: Array<any> | Object, key: any, val: any) {
 /**
  * Delete a property and trigger change if necessary.
  */
-export function del (obj: Array<any> | Object, key: any) {
-  if (Array.isArray(obj)) {
-    obj.splice(key, 1)
+export function del (target: Array<any> | Object, key: any) {
+  if (Array.isArray(target)) {
+    target.splice(key, 1)
     return
   }
-  const ob = obj.__ob__
-  if (obj._isVue || (ob && ob.vmCount)) {
+  const ob = target.__ob__
+  if (target._isVue || (ob && ob.vmCount)) {
     process.env.NODE_ENV !== 'production' && warn(
       'Avoid deleting properties on a Vue instance or its root $data ' +
       '- just set it to null.'
     )
     return
   }
-  if (!hasOwn(obj, key)) {
+  if (!hasOwn(target, key)) {
     return
   }
-  delete obj[key]
+  delete target[key]
   if (!ob) {
     return
   }

filename: test/unit/modules/observer/observer.spec.js
patch: @@ -312,15 +312,15 @@ describe('Observer', () => {
       data
     }).$mount()
     expect(vm.$el.outerHTML).toBe('<div>1</div>')
-    Vue.set(data, 'a', 2)
+    expect(Vue.set(data, 'a', 2)).toBe(2)
     waitForUpdate(() => {
       expect(vm.$el.outerHTML).toBe('<div>2</div>')
       expect('Avoid adding reactive properties to a Vue instance').not.toHaveBeenWarned()
       Vue.delete(data, 'a')
     }).then(() => {
       expect('Avoid deleting properties on a Vue instance').toHaveBeenWarned()
       expect(vm.$el.outerHTML).toBe('<div>2</div>')
-      Vue.set(data, 'b', 123)
+      expect(Vue.set(data, 'b', 123)).toBe(123)
       expect('Avoid adding reactive properties to a Vue instance').toHaveBeenWarned()
     }).then(done)
   })