Skip to content

Commit abe3be0

Browse files
authored
Merge pull request vuejs#282 from vuejs/feat/plugin-option-inferring
feat(types): infer options in plugins
2 parents 7eb0f27 + edf8fdc commit abe3be0

File tree

2 files changed

+60
-14
lines changed

2 files changed

+60
-14
lines changed

src/config.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@ interface GlobalConfigOptions {
1212
renderStubDefaultSlot: boolean
1313
}
1414

15-
interface Plugin<Instance> {
16-
handler: (
17-
instance: Instance,
18-
options: Record<string, any>
19-
) => Record<string, any>
20-
options: Record<string, any>
15+
interface Plugin<Instance, O> {
16+
handler(instance: Instance): Record<string, any>
17+
handler(instance: Instance, options: O): Record<string, any>
18+
options: O
2119
}
2220

2321
class Pluggable<Instance = DOMWrapper<Element>> {
24-
installedPlugins: Plugin<Instance>[] = []
22+
installedPlugins: Plugin<Instance, any>[] = []
2523

26-
install(
27-
handler: (
28-
instance: Instance,
29-
options?: Record<string, any>
30-
) => Record<string, any>,
31-
options: Record<string, any> = {}
24+
install<O>(handler: (instance: Instance) => Record<string, any>)
25+
install<O>(
26+
handler: (instance: Instance, options: O) => Record<string, any>,
27+
options: O
28+
)
29+
install<O>(
30+
handler: (instance: Instance, options?: O) => Record<string, any>,
31+
options?: O
3232
) {
3333
if (typeof handler !== 'function') {
3434
console.error('plugin.install must receive a function')
@@ -38,7 +38,7 @@ class Pluggable<Instance = DOMWrapper<Element>> {
3838
}
3939

4040
extend(instance: Instance) {
41-
const invokeSetup = ({ handler, options }: Plugin<Instance>) => {
41+
const invokeSetup = ({ handler, options }: Plugin<Instance, any>) => {
4242
return handler(instance, options) // invoke the setup method passed to install
4343
}
4444
const bindProperty = ([property, value]: [string, any]) => {

test-dts/plugins.d-test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { expectError, expectType } from 'tsd'
2+
import { ComponentPublicInstance } from 'vue'
3+
import { config, VueWrapper } from '../src'
4+
5+
interface OptionsI {
6+
msg: string
7+
}
8+
9+
function PluginWithOptions(
10+
wrapper: VueWrapper<ComponentPublicInstance>,
11+
options: OptionsI
12+
) {
13+
return {}
14+
}
15+
16+
function PluginWithoutOptions(wrapper: VueWrapper<ComponentPublicInstance>) {
17+
return {}
18+
}
19+
20+
function PluginWithOptionalOptions(
21+
wrapper: VueWrapper<ComponentPublicInstance>,
22+
options: OptionsI = { msg: 'hi' }
23+
) {
24+
return {}
25+
}
26+
27+
function PluginWithOptionalOptions2(
28+
wrapper: VueWrapper<ComponentPublicInstance>,
29+
options?: OptionsI
30+
) {
31+
return {}
32+
}
33+
34+
config.plugins.VueWrapper.install(PluginWithOptions, { msg: 'Hello' })
35+
config.plugins.VueWrapper.install(PluginWithoutOptions)
36+
config.plugins.VueWrapper.install(PluginWithOptionalOptions)
37+
config.plugins.VueWrapper.install(PluginWithOptionalOptions2)
38+
config.plugins.VueWrapper.install(PluginWithOptionalOptions, { msg: 'hello' })
39+
config.plugins.VueWrapper.install(PluginWithOptionalOptions2, { msg: 'hello' })
40+
41+
// uncertain if it is possible to forbid this usage
42+
// expectError(config.plugins.VueWrapper.install(PluginWithoutOptions, {}))
43+
expectError(config.plugins.VueWrapper.install(PluginWithOptions, { msg: true }))
44+
expectError(config.plugins.VueWrapper.install(PluginWithOptions, {}))
45+
expectError(config.plugins.VueWrapper.install(PluginWithOptionalOptions, {}))
46+
expectError(config.plugins.VueWrapper.install(PluginWithOptionalOptions2, {}))

0 commit comments

Comments
 (0)