Repository: vuejs/vue
Pull request: fix(model): allow arbitrary naems for type binding

Fix #6800

<!--
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)

- [x] Bugfix
- [ ] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [ ] 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:**


Changed files:
filename: src/platforms/web/compiler/modules/model.js
patch: @@ -36,7 +36,7 @@ function preTransformNode (el: ASTElement, options: CompilerOptions) {
       addRawAttr(branch0, 'type', 'checkbox')
       processElement(branch0, options)
       branch0.processed = true // prevent it from double-processed
-      branch0.if = `type==='checkbox'` + ifConditionExtra
+      branch0.if = `(${typeBinding})==='checkbox'` + ifConditionExtra
       addIfCondition(branch0, {
         exp: branch0.if,
         block: branch0
@@ -47,7 +47,7 @@ function preTransformNode (el: ASTElement, options: CompilerOptions) {
       addRawAttr(branch1, 'type', 'radio')
       processElement(branch1, options)
       addIfCondition(branch0, {
-        exp: `type==='radio'` + ifConditionExtra,
+        exp: `(${typeBinding})==='radio'` + ifConditionExtra,
         block: branch1
       })
       // 3. other

filename: test/unit/features/directives/model-dynamic.spec.js
patch: @@ -4,15 +4,15 @@ describe('Directive v-model dynamic input type', () => {
   it('should work', done => {
     const vm = new Vue({
       data: {
-        type: null,
+        inputType: null,
         test: 'b'
       },
-      template: `<input :type="type" v-model="test">`
+      template: `<input :type="inputType" v-model="test">`
     }).$mount()
     document.body.appendChild(vm.$el)
 
     // test text
-    assertInputWorks(vm).then(done)
+    assertInputWorks(vm, 'inputType').then(done)
   })
 
   it('with v-if', done => {
@@ -87,7 +87,11 @@ describe('Directive v-model dynamic input type', () => {
   })
 })
 
-function assertInputWorks (vm, chain) {
+function assertInputWorks (vm, type, chain) {
+  if (typeof type !== 'string') {
+    if (!chain) chain = type
+    type = 'type'
+  }
   if (!chain) chain = waitForUpdate()
   chain.then(() => {
     expect(vm.$el.value).toBe('b')
@@ -99,7 +103,7 @@ function assertInputWorks (vm, chain) {
     expect(vm.test).toBe('c')
   }).then(() => {
     // change it to password
-    vm.type = 'password'
+    vm[type] = 'password'
     vm.test = 'b'
   }).then(() => {
     expect(vm.$el.type).toBe('password')
@@ -109,7 +113,7 @@ function assertInputWorks (vm, chain) {
     expect(vm.test).toBe('c')
   }).then(() => {
     // change it to checkbox...
-    vm.type = 'checkbox'
+    vm[type] = 'checkbox'
   }).then(() => {
     expect(vm.$el.type).toBe('checkbox')
     expect(vm.$el.checked).toBe(true)