Skip to content

Commit 27e1c87

Browse files
committed
types: Added stricter type checking for plugin use
1 parent 4a3237a commit 27e1c87

File tree

4 files changed

+20
-11
lines changed

4 files changed

+20
-11
lines changed

packages/runtime-core/__tests__/apiCreateApp.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
Plugin,
1212
ref,
1313
getCurrentInstance,
14-
defineComponent
14+
defineComponent,
15+
App
1516
} from '@vue/runtime-test'
1617

1718
describe('api: createApp', () => {
@@ -273,12 +274,12 @@ describe('api: createApp', () => {
273274

274275
test('use', () => {
275276
const PluginA: Plugin = app => app.provide('foo', 1)
276-
const PluginB: Plugin = {
277-
install: (app, arg1, arg2) => app.provide('bar', arg1 + arg2)
277+
const PluginB = {
278+
install: (app: App, arg1: number, arg2: number) => app.provide('bar', arg1 + arg2)
278279
}
279280
class PluginC {
280281
someProperty = {}
281-
static install() {
282+
static install(app: App) {
282283
app.provide('baz', 2)
283284
}
284285
}

packages/runtime-core/src/apiCreateApp.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { ObjectEmitsOptions } from './componentEmits'
2828
export interface App<HostElement = any> {
2929
version: string
3030
config: AppConfig
31-
use(plugin: Plugin, ...options: any[]): this
31+
use<T extends Plugin>(plugin: T, ...options: ExtractPluginArg<T>): this
3232
mixin(mixin: ComponentOptions): this
3333
component(name: string): Component | undefined
3434
component(name: string, component: Component): this
@@ -139,12 +139,18 @@ export interface AppContext {
139139

140140
type PluginInstallFunction = (app: App, ...options: any[]) => any
141141

142-
export type Plugin =
143-
| (PluginInstallFunction & { install?: PluginInstallFunction })
142+
export type Plugin<T extends PluginInstallFunction = PluginInstallFunction> =
143+
| (T & { install?: T })
144144
| {
145-
install: PluginInstallFunction
145+
install: T
146146
}
147147

148+
export type ExtractPluginArg<T> = T extends Plugin<infer R>
149+
? R extends (app: App, ...arg: infer S) => any
150+
? S
151+
: never
152+
: never;
153+
148154
export function createAppContext(): AppContext {
149155
return {
150156
app: null as any,
@@ -215,7 +221,7 @@ export function createAppAPI<HostElement>(
215221
}
216222
},
217223

218-
use(plugin: Plugin, ...options: any[]) {
224+
use<T extends Plugin>(plugin: T, ...options: ExtractPluginArg<T>) {
219225
if (installedPlugins.has(plugin)) {
220226
__DEV__ && warn(`Plugin has already been applied to target app.`)
221227
} else if (plugin && isFunction(plugin.install)) {

packages/runtime-core/src/compat/global.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
AppConfig,
2424
AppContext,
2525
CreateAppFunction,
26+
ExtractPluginArg,
2627
Plugin
2728
} from '../apiCreateApp'
2829
import {
@@ -77,7 +78,7 @@ export type CompatVue = Pick<App, 'version' | 'component' | 'directive'> & {
7778

7879
nextTick: typeof nextTick
7980

80-
use(plugin: Plugin, ...options: any[]): CompatVue
81+
use<T extends Plugin>(plugin: T, ...options: ExtractPluginArg<T>): CompatVue
8182
mixin(mixin: ComponentOptions): CompatVue
8283

8384
component(name: string): Component | undefined

packages/runtime-core/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ export {
189189
AppContext,
190190
Plugin,
191191
CreateAppFunction,
192-
OptionMergeFunction
192+
OptionMergeFunction,
193+
ExtractPluginArg
193194
} from './apiCreateApp'
194195
export {
195196
VNode,

0 commit comments

Comments
 (0)