Repository: vuejs/vue
Pull request: fix(types): contravariant generic default in ComponentOption

**What kind of change does this PR introduce?** (check at least one)

- [x] Bugfix


**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

**Other information:**

Fix bugs spotted in https://github.com/vuejs/vue-test-utils/pull/317#discussion_r159149553.

Some type theory shenanigans below:

This pull request allows assigning `ComponentOption` of a Vue subclass to `Component`. The problem is that we used to mark default vm type  as `Vue` in `Component`. However, since `ComponentOption` is contravariant against vm type `V`. The default bound should not be the upper bound `Vue`, but the lower bound `never`.

For a more concrete example, consider this usage:

```ts
interface MyComponent extends Vue {
   num: number;
 }
 
const option: ComponentOptions<MyComponent> = {
  // a lifetime method
  created(this: MyComponent) { return this.num.toFixed() }
}
```

Then, assigning option to `ComponentOption<Vue>`, we could in theory do unsafe operation:

```ts
const anotherOption: ComponentOptions<Vue> = option

anotherOption.created.call(new Vue) // error! no property num on Vue!
```

Though it is not how we really use Vue, type checker cannot know this. To workaround, we can mark  `anotherOption` to have vm type as `never`.  `never` is the bottom type of any type, so `ComponentOption<never>`'s `create` method can accept nothing, and thusly any `create` method from subclass can satisfy _accepting nothing_ semantic. In practical words, this means we promise that we **never** use `created` like the way above. 

Changed files:
filename: types/options.d.ts
patch: @@ -6,16 +6,17 @@ type Constructor = {
 }
 
 // we don't support infer props in async component
-export type Component<Data=DefaultData<Vue>, Methods=DefaultMethods<Vue>, Computed=DefaultComputed, Props=DefaultProps> =
+// N.B. ComponentOptions<V> is contravariant, the default generic should be bottom type
+export type Component<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> =
   | typeof Vue
   | FunctionalComponentOptions<Props>
-  | ComponentOptions<Vue, Data, Methods, Computed, Props>
+  | ComponentOptions<never, Data, Methods, Computed, Props>
 
 interface EsModuleComponent {
   default: Component
 }
 
-export type AsyncComponent<Data=DefaultData<Vue>, Methods=DefaultMethods<Vue>, Computed=DefaultComputed, Props=DefaultProps> = (
+export type AsyncComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = (
   resolve: (component: Component<Data, Methods, Computed, Props>) => void,
   reject: (reason?: any) => void
 ) => Promise<Component | EsModuleComponent> | void;

filename: types/test/options-test.ts
patch: @@ -1,11 +1,23 @@
 import Vue, { VNode } from "../index";
-import { AsyncComponent, ComponentOptions, FunctionalComponentOptions } from "../index";
+import { AsyncComponent, ComponentOptions, FunctionalComponentOptions, Component } from "../index";
 import { CreateElement } from "../vue";
 
-interface Component extends Vue {
+interface MyComponent extends Vue {
   a: number;
 }
 
+const option: ComponentOptions<MyComponent> = {
+  data() {
+    return {
+      a: 123
+    }
+  }
+}
+
+// contravariant generic should use never
+const anotherOption: ComponentOptions<never> = option
+const componentType: Component = option
+
 Vue.component('sub-component', {
   components: {
     a: Vue.component(""),
@@ -41,10 +53,10 @@ Vue.component('string-prop', {
 });
 
 class User {
-  private u: number
+  private u = 1
 }
 class Cat {
-  private u: number
+  private u = 1
 }
 
 Vue.component('union-prop', {