Skip to content

Commit b7cf3ad

Browse files
types: allow any number of settings to be passed to a plugin
uses variadic function with tuple based type checking to ensure settings and parameters match up.
1 parent 8c0285c commit b7cf3ad

File tree

2 files changed

+35
-41
lines changed

2 files changed

+35
-41
lines changed

types/index.d.ts

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// TypeScript Version: 3.0
1+
// TypeScript Version: 3.4
22

33
import {Node} from 'unist'
44
import {VFile, VFileContents, VFileOptions} from 'vfile'
@@ -23,33 +23,29 @@ declare namespace unified {
2323
*
2424
* @param plugin unified plugin
2525
* @param settings Configuration for plugin
26-
* @param extraSettings Additional configuration for plugin
2726
* @typeParam S Plugin settings
28-
* @typeParam S2 Extra plugin settings
2927
* @returns The processor on which use is invoked
3028
*/
31-
use<S = Settings, S2 = undefined>(
32-
plugin: Plugin<S, S2, P>,
33-
settings?: S,
34-
extraSettings?: S2
29+
use<S extends any[] = [Settings?]>(
30+
plugin: Plugin<S, P>,
31+
...settings: S
3532
): Processor<P>
3633

3734
/**
3835
* Configure the processor with a preset to use
3936
*
4037
* @param preset `Object` with an plugins (set to list), and/or an optional settings object
4138
*/
42-
use(preset: Preset<P>): Processor<P>
39+
use<S extends any[] = [Settings?]>(preset: Preset<S, P>): Processor<P>
4340

4441
/**
4542
* Configure using a tuple of plugin and setting(s)
4643
*
4744
* @param pluginTuple pairs, plugin and settings in an array
4845
* @typeParam S Plugin settings
49-
* @typeParam S2 Extra plugin settings
5046
*/
51-
use<S = Settings, S2 = Settings>(
52-
pluginTuple: PluginTuple<S, S2, P>
47+
use<S extends any[] = [Settings?]>(
48+
pluginTuple: PluginTuple<S, P>
5349
): Processor<P>
5450

5551
/**
@@ -214,13 +210,11 @@ declare namespace unified {
214210
*
215211
* @this Processor context object is set to the invoked on processor.
216212
* @param settings Configuration
217-
* @param extraSettings Secondary configuration
218213
* @typeParam S Plugin settings
219-
* @typeParam S2 Extra plugin settings
220214
* @typeParam P Processor settings
221215
* @returns Optional Transformer.
222216
*/
223-
type Plugin<S = Settings, S2 = undefined, P = Settings> = Attacher<S, S2, P>
217+
type Plugin<S extends any[] = [Settings?], P = Settings> = Attacher<S, P>
224218

225219
/**
226220
* Configuration passed to a Plugin or Processor
@@ -235,7 +229,7 @@ declare namespace unified {
235229
*
236230
* @typeParam P Processor settings
237231
*/
238-
interface Preset<P = Settings> {
232+
interface Preset<S = Settings, P = Settings> {
239233
plugins: PluggableList<P>
240234
settings?: Settings
241235
}
@@ -253,31 +247,35 @@ declare namespace unified {
253247
* A pairing of a plugin with its settings
254248
*
255249
* @typeParam S Plugin settings
256-
* @typeParam S2 Extra plugin settings
257250
* @typeParam P Processor settings
258251
*/
259-
type PluginTuple<S = Settings, S2 = undefined, P = Settings> =
260-
| [Plugin<S, undefined, P>, S]
261-
| [Plugin<S, S2, P>, S, S2]
252+
type PluginTuple<S extends any[] = [Settings?], P = Settings> = [
253+
Plugin<S, P>,
254+
/**
255+
* NOTE: ideally this would be S instead of any[]
256+
* As of TypeScript 3.5.2 generic tuples cannot be spread
257+
* See: https://github.com/microsoft/TypeScript/issues/26113
258+
*/
259+
...any[]
260+
]
262261

263262
/**
264263
* A union of the different ways to add plugins to unified
265264
*
266265
* @typeParam S Plugin settings
267-
* @typeParam S2 Extra plugin settings
268266
* @typeParam P Processor settings
269267
*/
270-
type Pluggable<S = Settings, S2 = undefined, P = Settings> =
271-
| Plugin<S, S2, P>
272-
| Preset<P>
273-
| PluginTuple<S, S2, P>
268+
type Pluggable<S extends any[] = [Settings?], P = Settings> =
269+
| Plugin<S, P>
270+
| Preset<S, P>
271+
| PluginTuple<S, P>
274272

275273
/**
276274
* A list of plugins and presets
277275
*
278276
* @typeParam P Processor settings
279277
*/
280-
type PluggableList<P = Settings> = Array<Pluggable<any, any, P>>
278+
type PluggableList<P = Settings> = Array<Pluggable<[any?], P>>
281279

282280
/**
283281
* An attacher is the thing passed to `use`.
@@ -287,14 +285,12 @@ declare namespace unified {
287285
*
288286
* @this Processor context object is set to the invoked on processor.
289287
* @param settings Configuration
290-
* @param extraSettings Secondary configuration
291288
* @typeParam S Plugin settings
292-
* @typeParam S2 Extra plugin settings
293289
* @typeParam P Processor settings
294290
* @returns Optional Transformer.
295291
*/
296-
interface Attacher<S = Settings, S2 = undefined, P = Settings> {
297-
(this: Processor<P>, settings?: S, extraSettings?: S2): Transformer | void
292+
interface Attacher<S extends any[] = [Settings?], P = Settings> {
293+
(this: Processor<P>, ...settings: S): Transformer | void
298294
}
299295

300296
/**

types/unified-tests.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const settings = {
3030
interface ExamplePluginSettings {
3131
example: string
3232
}
33-
const typedPlugin: Plugin<ExamplePluginSettings> = function() {}
33+
const typedPlugin: Plugin<[ExamplePluginSettings?]> = function() {}
3434
const typedSetting = {example: 'example'}
3535

3636
const implicitlyTypedPlugin = (settings?: ExamplePluginSettings) => {}
@@ -51,31 +51,34 @@ processor.use([[plugin, settings], [plugin, settings]])
5151
processor.use(typedPlugin)
5252
processor.use(typedPlugin).use(typedPlugin)
5353
processor.use(typedPlugin, typedSetting)
54+
// NOTE: in tuple/array form settings are not able to be type checked
5455
processor.use([typedPlugin, typedSetting])
5556
processor.use([[typedPlugin, typedSetting], [typedPlugin, typedSetting]])
5657
processor.use([[plugin, settings], [typedPlugin, typedSetting]])
5758
processor.use([typedPlugin])
59+
processor.use([typedPlugin, typedSetting, settings])
60+
processor.use([typedPlugin, settings])
5861

5962
processor.use(implicitlyTypedPlugin)
6063
processor.use(implicitlyTypedPlugin).use(implicitlyTypedPlugin)
6164
processor.use(implicitlyTypedPlugin, typedSetting)
65+
// NOTE: in tuple/array form settings are not able to be type checked
6266
processor.use([implicitlyTypedPlugin, typedSetting])
6367
processor.use([
6468
[implicitlyTypedPlugin, typedSetting],
6569
[implicitlyTypedPlugin, typedSetting]
6670
])
6771
processor.use([[plugin, settings], [implicitlyTypedPlugin, typedSetting]])
6872
processor.use([implicitlyTypedPlugin])
69-
70-
// NOTE: settings overrides the generic undefined
71-
// settings value will be unused but TypeScript will not warn
72-
processor.use(implicitlyTypedPlugin, typedSetting, settings)
73+
processor.use([implicitlyTypedPlugin, settings])
7374
processor.use([implicitlyTypedPlugin, typedSetting, settings])
7475

7576
processor.use(pluginWithTwoSettings)
7677
processor.use(pluginWithTwoSettings).use(pluginWithTwoSettings)
7778
processor.use(pluginWithTwoSettings, processor, typedSetting)
7879
processor.use(pluginWithTwoSettings, processor)
80+
// NOTE: in tuple/array form settings are not able to be type checked
81+
processor.use([pluginWithTwoSettings, processor, settings])
7982
processor.use([pluginWithTwoSettings, processor, typedSetting])
8083
processor.use([pluginWithTwoSettings, processor])
8184
processor.use([
@@ -91,16 +94,12 @@ processor.use([pluginWithTwoSettings])
9194
// $ExpectError
9295
processor.use(typedPlugin, settings)
9396
// $ExpectError
94-
processor.use([typedPlugin, settings])
95-
// $ExpectError
9697
processor.use(typedPlugin, typedSetting, settings)
97-
// $ExpectError
98-
processor.use([typedPlugin, typedSetting, settings])
9998

10099
// $ExpectError
101100
processor.use(implicitlyTypedPlugin, settings)
102101
// $ExpectError
103-
processor.use([implicitlyTypedPlugin, settings])
102+
processor.use(implicitlyTypedPlugin, typedSetting, settings)
104103

105104
// $ExpectError
106105
processor.use(pluginWithTwoSettings, typedSetting)
@@ -109,8 +108,6 @@ processor.use(pluginWithTwoSettings, typedSetting)
109108

110109
// $ExpectError
111110
processor.use(pluginWithTwoSettings, processor, settings)
112-
// $ExpectError
113-
processor.use([pluginWithTwoSettings, processor, settings])
114111

115112
// $ExpectError
116113
processor.use({})
@@ -141,6 +138,7 @@ processor.use({
141138
processor.use({
142139
settings: {}
143140
})
141+
144142
processor.use({
145143
plugins: [plugin]
146144
})

0 commit comments

Comments
 (0)