소스 검색

types: enhance plugin type inference for better IDE support (#13063)

* types: enhance plugin type inference for better JSDoc and IDE support

* test: clean up

* chore: tweaks
Tycho 1 년 전
부모
커밋
f6f64befb8
2개의 변경된 파일45개의 추가작업 그리고 6개의 파일을 삭제
  1. 38 1
      packages-private/dts-test/appUse.test-d.ts
  2. 7 5
      packages/runtime-core/src/apiCreateApp.ts

+ 38 - 1
packages-private/dts-test/appUse.test-d.ts

@@ -12,8 +12,11 @@ app.use(PluginWithoutType, 2)
 app.use(PluginWithoutType, { anything: 'goes' }, true)
 
 type PluginOptions = {
+  /** option1 */
   option1?: string
+  /** option2 */
   option2: number
+  /** option3 */
   option3: boolean
 }
 
@@ -25,6 +28,20 @@ const PluginWithObjectOptions = {
   },
 }
 
+const objectPluginOptional = {
+  install(app: App, options?: PluginOptions) {},
+}
+app.use(objectPluginOptional)
+app.use(
+  objectPluginOptional,
+  // Test JSDoc and `go to definition` for options
+  {
+    option1: 'foo',
+    option2: 1,
+    option3: true,
+  },
+)
+
 for (const Plugin of [
   PluginWithObjectOptions,
   PluginWithObjectOptions.install,
@@ -92,7 +109,27 @@ const PluginTyped: Plugin<PluginOptions> = (app, options) => {}
 
 // @ts-expect-error: needs options
 app.use(PluginTyped)
-app.use(PluginTyped, { option2: 2, option3: true })
+app.use(
+  PluginTyped,
+  // Test autocomplete for options
+  {
+    option1: '',
+    option2: 2,
+    option3: true,
+  },
+)
+
+const functionPluginOptional = (app: App, options?: PluginOptions) => {}
+app.use(functionPluginOptional)
+app.use(functionPluginOptional, { option2: 2, option3: true })
+
+// type optional params
+const functionPluginOptional2: Plugin<[options?: PluginOptions]> = (
+  app,
+  options,
+) => {}
+app.use(functionPluginOptional2)
+app.use(functionPluginOptional2, { option2: 2, option3: true })
 
 // vuetify usage
 const key: string = ''

+ 7 - 5
packages/runtime-core/src/apiCreateApp.ts

@@ -36,9 +36,9 @@ export interface App<HostElement = any> {
 
   use<Options extends unknown[]>(
     plugin: Plugin<Options>,
-    ...options: Options
+    ...options: NoInfer<Options>
   ): this
-  use<Options>(plugin: Plugin<Options>, options: Options): this
+  use<Options>(plugin: Plugin<Options>, options: NoInfer<Options>): this
 
   mixin(mixin: ComponentOptions): this
   component(name: string): Component | undefined
@@ -215,9 +215,11 @@ export type ObjectPlugin<Options = any[]> = {
 export type FunctionPlugin<Options = any[]> = PluginInstallFunction<Options> &
   Partial<ObjectPlugin<Options>>
 
-export type Plugin<Options = any[]> =
-  | FunctionPlugin<Options>
-  | ObjectPlugin<Options>
+export type Plugin<
+  Options = any[],
+  // TODO: in next major Options extends unknown[] and remove P
+  P extends unknown[] = Options extends unknown[] ? Options : [Options],
+> = FunctionPlugin<P> | ObjectPlugin<P>
 
 export function createAppContext(): AppContext {
   return {