diff --git a/packages/weex-vue-framework/factory.js b/packages/weex-vue-framework/factory.js
index 8bcfb675ba9..fb30d12bbbd 100644
--- a/packages/weex-vue-framework/factory.js
+++ b/packages/weex-vue-framework/factory.js
@@ -5797,7 +5797,7 @@ function createPatchFunction (backend) {
     }
   }
 
-  function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
+  function removeVnodes (vnodes, startIdx, endIdx) {
     for (; startIdx <= endIdx; ++startIdx) {
       var ch = vnodes[startIdx];
       if (isDef(ch)) {
@@ -5908,7 +5908,7 @@ function createPatchFunction (backend) {
       refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;
       addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
     } else if (newStartIdx > newEndIdx) {
-      removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
+      removeVnodes(oldCh, oldStartIdx, oldEndIdx);
     }
   }
 
@@ -5985,7 +5985,7 @@ function createPatchFunction (backend) {
         if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }
         addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
       } else if (isDef(oldCh)) {
-        removeVnodes(elm, oldCh, 0, oldCh.length - 1);
+        removeVnodes(oldCh, 0, oldCh.length - 1);
       } else if (isDef(oldVnode.text)) {
         nodeOps.setTextContent(elm, '');
       }
@@ -6216,7 +6216,7 @@ function createPatchFunction (backend) {
 
         // destroy old node
         if (isDef(parentElm$1)) {
-          removeVnodes(parentElm$1, [oldVnode], 0, 0);
+          removeVnodes([oldVnode], 0, 0);
         } else if (isDef(oldVnode.tag)) {
           invokeDestroyHook(oldVnode);
         }
diff --git a/src/compiler/error-detector.js b/src/compiler/error-detector.js
index 22c3b75d3aa..9893aa4a47a 100644
--- a/src/compiler/error-detector.js
+++ b/src/compiler/error-detector.js
@@ -36,6 +36,8 @@ function checkNode (node: ASTNode, warn: Function) {
           const range = node.rawAttrsMap[name]
           if (name === 'v-for') {
             checkFor(node, `v-for="${value}"`, warn, range)
+          } else if (name === 'v-slot' || name[0] === '#') {
+            checkFunctionParameterExpression(value, `${name}="${value}"`, warn, range)
           } else if (onRE.test(name)) {
             checkEvent(value, `${name}="${value}"`, warn, range)
           } else {
@@ -111,3 +113,16 @@ function checkExpression (exp: string, text: string, warn: Function, range?: Ran
     }
   }
 }
+
+function checkFunctionParameterExpression (exp: string, text: string, warn: Function, range?: Range) {
+  try {
+    new Function(exp, '')
+  } catch (e) {
+    warn(
+      `invalid function parameter expression: ${e.message} in\n\n` +
+      `    ${exp}\n\n` +
+      `  Raw expression: ${text.trim()}\n`,
+      range
+    )
+  }
+}
diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js
index fb258752179..cdeb257eda4 100644
--- a/src/compiler/parser/index.js
+++ b/src/compiler/parser/index.js
@@ -23,8 +23,8 @@ import {
 
 export const onRE = /^@|^v-on:/
 export const dirRE = process.env.VBIND_PROP_SHORTHAND
-  ? /^v-|^@|^:|^\./
-  : /^v-|^@|^:/
+  ? /^v-|^@|^:|^\.|^#/
+  : /^v-|^@|^:|^#/
 export const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
 export const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/
 const stripParensRE = /^\(|\)$/g
diff --git a/src/core/util/env.js b/src/core/util/env.js
index eff1d21dc75..820bacdb405 100644
--- a/src/core/util/env.js
+++ b/src/core/util/env.js
@@ -87,11 +87,10 @@ if (typeof Set !== 'undefined' && isNative(Set)) {
   }
 }
 
-interface SimpleSet {
+export interface SimpleSet {
   has(key: string | number): boolean;
   add(key: string | number): mixed;
   clear(): void;
 }
 
 export { _Set }
-export type { SimpleSet }
diff --git a/src/core/vdom/create-element.js b/src/core/vdom/create-element.js
index 46027084b51..ba36e15b12d 100644
--- a/src/core/vdom/create-element.js
+++ b/src/core/vdom/create-element.js
@@ -98,6 +98,12 @@ export function _createElement (
     ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
     if (config.isReservedTag(tag)) {
       // platform built-in elements
+      if (process.env.NODE_ENV !== 'production' && isDef(data) && isDef(data.nativeOn)) {
+        warn(
+          `The .native modifier for v-on is only valid on components but it was used on <${tag}>.`,
+          context
+        )
+      }
       vnode = new VNode(
         config.parsePlatformTagName(tag), data, children,
         undefined, undefined, context
diff --git a/src/core/vdom/patch.js b/src/core/vdom/patch.js
index 9746bb794f8..95a4db47298 100644
--- a/src/core/vdom/patch.js
+++ b/src/core/vdom/patch.js
@@ -16,6 +16,7 @@ import { SSR_ATTR } from 'shared/constants'
 import { registerRef } from './modules/ref'
 import { traverse } from '../observer/traverse'
 import { activeInstance } from '../instance/lifecycle'
+import { inBrowser } from '../util/index';
 import { isTextInputType } from 'web/util/element'
 
 import {
@@ -32,6 +33,8 @@ export const emptyNode = new VNode('', {}, [])
 
 const hooks = ['create', 'activate', 'update', 'remove', 'destroy']
 
+const customElements = inBrowser ? window.customElements : undefined
+
 function sameVnode (a, b) {
   return (
     a.key === b.key && (
@@ -106,6 +109,7 @@ export function createPatchFunction (backend) {
 
   function isUnknownElement (vnode, inVPre) {
     return (
+      !(customElements && customElements.get(vnode.tag)) &&
       !inVPre &&
       !vnode.ns &&
       !(
@@ -358,7 +362,7 @@ export function createPatchFunction (backend) {
     }
   }
 
-  function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
+  function removeVnodes (vnodes, startIdx, endIdx) {
     for (; startIdx <= endIdx; ++startIdx) {
       const ch = vnodes[startIdx]
       if (isDef(ch)) {
@@ -469,7 +473,7 @@ export function createPatchFunction (backend) {
       refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
       addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
     } else if (newStartIdx > newEndIdx) {
-      removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
+      removeVnodes(oldCh, oldStartIdx, oldEndIdx)
     }
   }
 
@@ -561,7 +565,7 @@ export function createPatchFunction (backend) {
         if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '')
         addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue)
       } else if (isDef(oldCh)) {
-        removeVnodes(elm, oldCh, 0, oldCh.length - 1)
+        removeVnodes(oldCh, 0, oldCh.length - 1)
       } else if (isDef(oldVnode.text)) {
         nodeOps.setTextContent(elm, '')
       }
@@ -790,7 +794,7 @@ export function createPatchFunction (backend) {
 
         // destroy old node
         if (isDef(parentElm)) {
-          removeVnodes(parentElm, [oldVnode], 0, 0)
+          removeVnodes([oldVnode], 0, 0)
         } else if (isDef(oldVnode.tag)) {
           invokeDestroyHook(oldVnode)
         }
diff --git a/test/e2e/nightwatch.config.js b/test/e2e/nightwatch.config.js
index 2004f92b45b..8ec592494fe 100644
--- a/test/e2e/nightwatch.config.js
+++ b/test/e2e/nightwatch.config.js
@@ -50,7 +50,8 @@ module.exports = {
       'desiredCapabilities': {
         'browserName': 'phantomjs',
         'javascriptEnabled': true,
-        'acceptSslCerts': true
+        'acceptSslCerts': true,
+        'phantomjs.binary.path': require('phantomjs-prebuilt').path
       }
     }
   }
diff --git a/test/unit/features/component/component-scoped-slot.spec.js b/test/unit/features/component/component-scoped-slot.spec.js
index f8a0f11b7fa..28369814f48 100644
--- a/test/unit/features/component/component-scoped-slot.spec.js
+++ b/test/unit/features/component/component-scoped-slot.spec.js
@@ -759,6 +759,22 @@ describe('Component scoped slot', () => {
         }).$mount()
         expect(`Unexpected mixed usage of different slot syntaxes`).toHaveBeenWarned()
       })
+
+      it('should warn invalid parameter expression', () => {
+        new Vue({
+          template: `<foo ${syntax}="1"></foo>`,
+          components: { Foo }
+        }).$mount();
+        expect('invalid function parameter expression').toHaveBeenWarned()
+      })
+
+      it('should allow destructuring props with default value', () => {
+        new Vue({
+          template: `<foo ${syntax}="{ foo = { bar: '1' } }"></foo>`,
+          components: { Foo }
+        }).$mount();
+        expect('invalid function parameter expression').not.toHaveBeenWarned()
+      })
     }
 
     // run tests for both full syntax and shorthand
diff --git a/test/unit/features/directives/on.spec.js b/test/unit/features/directives/on.spec.js
index a97ddaa8947..b7801a82f22 100644
--- a/test/unit/features/directives/on.spec.js
+++ b/test/unit/features/directives/on.spec.js
@@ -460,6 +460,20 @@ describe('Directive v-on', () => {
     expect(spy).toHaveBeenCalled()
   })
 
+  it('should throw a warning if native modifier is used on native HTML element', () => {
+    vm = new Vue({
+      el,
+      template: `
+        <button @click.native="foo"></button>
+      `,
+      methods: { foo: spy },
+    })
+
+    triggerEvent(vm.$el, 'click')
+    expect(`The .native modifier for v-on is only valid on components but it was used on <button>.`).toHaveBeenWarned()
+    expect(spy.calls.count()).toBe(0)
+  })
+
   it('.once modifier should work with child components', () => {
     vm = new Vue({
       el,
diff --git a/types/index.d.ts b/types/index.d.ts
index b0e24d767e9..58ceb209e5d 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -1,9 +1,8 @@
 import { Vue } from "./vue";
+import "./umd";
 
 export default Vue;
 
-export as namespace Vue;
-
 export {
   CreateElement,
   VueConstructor
diff --git a/types/test/options-test.ts b/types/test/options-test.ts
index b8bdc098312..28060b7c817 100644
--- a/types/test/options-test.ts
+++ b/types/test/options-test.ts
@@ -76,10 +76,6 @@ Vue.component('union-prop', {
     complexUnion: { type: [User, Number] as PropType<User | number> },
     kittyUser: Object as PropType<ICat & IUser>,
     callback: Function as PropType<ConfirmCallback>,
-    mixed: [RegExp, Array],
-    object: [Cat, User],
-    primitive: [String, Number],
-    regex: RegExp,
     union: [User, Number] as PropType<User | number>
   },
   data() {
@@ -87,10 +83,6 @@ Vue.component('union-prop', {
     this.complexUnion;
     this.kittyUser;
     this.callback(true);
-    this.mixed;
-    this.object;
-    this.primitive;
-    this.regex.compile;
     this.union;
     return {
       fixedSize: this.union,
@@ -98,6 +90,22 @@ Vue.component('union-prop', {
   }
 });
 
+// stopped working since TS 3.4
+// Vue.component('union-prop-with-no-casting', {
+//   props: {
+//     mixed: [RegExp, Array],
+//     object: [Cat, User],
+//     primitive: [String, Number],
+//     regex: RegExp
+//   },
+//   data() {
+//     this.mixed;
+//     this.object;
+//     this.primitive;
+//     this.regex.compile;
+//   }
+// })
+
 Vue.component('prop-with-primitive-default', {
   props: {
     id: {
diff --git a/types/test/tsconfig.json b/types/test/tsconfig.json
index b816ce07cdc..dab30a608bf 100644
--- a/types/test/tsconfig.json
+++ b/types/test/tsconfig.json
@@ -14,17 +14,9 @@
       "vue": ["../index.d.ts"]
     }
   },
-  "files": [
-    "../index.d.ts",
-    "../options.d.ts",
-    "../plugin.d.ts",
-    "../vnode.d.ts",
-    "../vue.d.ts",
-    "options-test.ts",
-    "plugin-test.ts",
-    "vue-test.ts",
-    "augmentation-test.ts",
-    "ssr-test.ts"
+  "include": [
+    "../*.d.ts",
+    "*.ts"
   ],
   "compileOnSave": false
 }
diff --git a/types/test/umd-test.ts b/types/test/umd-test.ts
new file mode 100644
index 00000000000..ffdc7046f92
--- /dev/null
+++ b/types/test/umd-test.ts
@@ -0,0 +1,7 @@
+const vm = new Vue({
+  template: "<div>hi</div>"
+});
+
+const options: Vue.ComponentOptions<Vue> = {
+  template: "<div>test</div>"
+};
diff --git a/types/umd.d.ts b/types/umd.d.ts
new file mode 100644
index 00000000000..618d484e48d
--- /dev/null
+++ b/types/umd.d.ts
@@ -0,0 +1,48 @@
+import * as V from "./index";
+import {
+  DefaultData,
+  DefaultProps,
+  DefaultMethods,
+  DefaultComputed,
+  PropsDefinition
+} from "./options";
+
+// Expose some types for backword compatibility...
+declare namespace Vue {
+  // vue.d.ts
+  export type CreateElement = V.CreateElement;
+  export type VueConstructor<V extends Vue = Vue> = V.VueConstructor<V>;
+
+  // options.d.ts
+  export type Component<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = V.Component<Data, Methods, Computed, Props>;
+  export type AsyncComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = V.AsyncComponent<Data, Methods, Computed, Props>;
+  export type ComponentOptions<V extends Vue, Data=DefaultData<V>, Methods=DefaultMethods<V>, Computed=DefaultComputed, PropsDef=PropsDefinition<DefaultProps>, Props=DefaultProps> = V.ComponentOptions<V, Data, Methods, Computed, PropsDef, Props>;
+  export type FunctionalComponentOptions<Props = DefaultProps, PropDefs = PropsDefinition<Props>> = V.FunctionalComponentOptions<Props, PropDefs>;
+  export type RenderContext<Props=DefaultProps> = V.RenderContext<Props>;
+  export type PropType<T> = V.PropType<T>;
+  export type PropOptions<T=any> = V.PropOptions<T>;
+  export type ComputedOptions<T> = V.ComputedOptions<T>;
+  export type WatchHandler<T> = V.WatchHandler<T>;
+  export type WatchOptions = V.WatchOptions;
+  export type WatchOptionsWithHandler<T> = V.WatchOptionsWithHandler<T>;
+  export type DirectiveFunction = V.DirectiveFunction;
+  export type DirectiveOptions = V.DirectiveOptions;
+
+  // plugin.d.ts
+  export type PluginFunction<T> = V.PluginFunction<T>;
+  export type PluginObject<T> = V.PluginObject<T>;
+
+  // vnode.d.ts
+  export type VNodeChildren = V.VNodeChildren;
+  export type VNodeChildrenArrayContents = V.VNodeChildrenArrayContents;
+  export type VNode = V.VNode;
+  export type VNodeComponentOptions = V.VNodeComponentOptions;
+  export type VNodeData = V.VNodeData;
+  export type VNodeDirective = V.VNodeDirective;
+}
+
+declare class Vue extends V.default {}
+
+export = Vue;
+
+export as namespace Vue;