Repository: vuejs/vue
Pull request: fix(types): fix prop constructor type inference

<!--
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
- [x] 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
- [ ] 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:**
I found that for some reason `any` type in `new (...args: any[]): T & object`  prevent to pick up prop type in the newer TypeScript version. Replacing it with `never` fixes the problem.

The meaning of the code is not changed as a function argument type is contravariant and `never` type is of bottom type, that is, the entire `new (...args: never[]): T & object` type accepts any constructor type having any argument types which the original code intends.

Changed files:
filename: package.json
patch: @@ -74,7 +74,7 @@
     "@babel/plugin-transform-flow-strip-types": "^7.0.0",
     "@babel/preset-env": "^7.0.0",
     "@babel/register": "^7.0.0",
-    "@types/node": "^10.12.18",
+    "@types/node": "^12.12.0",
     "@types/webpack": "^4.4.22",
     "acorn": "^5.2.1",
     "babel-eslint": "^10.0.1",
@@ -136,7 +136,7 @@
     "serialize-javascript": "^1.3.0",
     "shelljs": "^0.8.1",
     "terser": "^3.10.2",
-    "typescript": "^3.1.3",
+    "typescript": "^3.6.4",
     "webpack": "~4.28.4",
     "weex-js-runtime": "^0.23.6",
     "weex-styler": "^0.3.0",

filename: types/options.d.ts
patch: @@ -144,7 +144,7 @@ export interface RenderContext<Props=DefaultProps> {
   injections: any
 }
 
-export type Prop<T> = { (): T } | { new(...args: any[]): T & object } | { new(...args: string[]): Function }
+export type Prop<T> = { (): T } | { new(...args: never[]): T & object } | { new(...args: string[]): Function }
 
 export type PropType<T> = Prop<T> | Prop<T>[];
 

filename: types/test/options-test.ts
patch: @@ -90,21 +90,20 @@ 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('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: {
@@ -113,7 +112,7 @@ Vue.component('prop-with-primitive-default', {
       default: () => String(Math.round(Math.random() * 10000000))
     }
   },
-  created() {
+  created(): void {
     this.id;
   }
 });
@@ -152,7 +151,7 @@ Vue.component('component', {
     }
   },
   methods: {
-    plus() {
+    plus(): void {
       this.a++;
       this.aDouble.toFixed();
       this.aPlus = 1;

filename: yarn.lock
patch: @@ -675,11 +675,16 @@
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
   integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
 
-"@types/node@*", "@types/node@^10.12.18":
+"@types/node@*":
   version "10.12.18"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
   integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
 
+"@types/node@^12.12.0":
+  version "12.12.0"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.0.tgz#ff3201972d6dc851a9275308a17b9b5094e68057"
+  integrity sha512-6N8Sa5AaENRtJnpKXZgvc119PKxT1Lk9VPy4kfT8JF23tIe1qDfaGkBR2DRKJFIA7NptMz+fps//C6aLi1Uoug==
+
 "@types/tapable@*":
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
@@ -7927,10 +7932,10 @@ typedarray@^0.0.6:
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-typescript@^3.1.3:
-  version "3.2.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
-  integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
+typescript@^3.6.4:
+  version "3.6.4"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
+  integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
 
 uglify-js@^3.1.4:
   version "3.6.1"