Open Derugon opened 8 months ago
You will find an initial implementation in this branch: https://github.com/Derugon/types-mediawiki/tree/split (based on the https://github.com/wikimedia-gadgets/types-mediawiki/pull/36 MR branch, diff comparison here).
(note that none of the missing modules have been added to this branch, so some modules are empty (for now): they have only been added to validate other module dependencies)
Alternative B is used here: one folder per module. What I didn't thought about is that unlike alternatives A and C, this alternative allows .../node_modules/types-mediawiki
to be treated as a type root,
The organisation of files within a module is similar to the one currently used (roughly one file per namespace).
After a few failed and successful attempts at implementing the previously mentioned alternatives:
Using declare module { ... }
seems to properly extend existing modules, but I'm not familiar enough with this syntax to find a way to declare new modules without creating real files and folders.
Another issue I didn't consider is that all global declarations are always visible, if the files they come from have been scanned by the TS compiler. The recommended approach in the README is to use "include": ["./node_modules/types-mediawiki"]
so all declaration files are included, and also all globals are always visible. The only way I was able to find to hide global declarations is to prevent the complier from scanning declaration files (which also disables sub-module autocompletion in import
). This way we could instead recommend the use of typeRoots
:
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./node_modules/types-mediawiki"]
}
Then, one may only enable a few MediaWiki modules by specifying types
:
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./node_modules/types-mediawiki"],
"types": ["mediawiki.base", "mediawiki.ForeignApi", "mediawiki.language"]
}
This approach also requires having one folder per sub-module, because single declaration files (e.g. mediawiki.ForeignApi.d.ts
module file in root library folder) do not seem to be scanned properly. We would then have:
resources/src/startup/
).mediawiki.api
, mediawiki.base
, mediawiki.cldr
, etc.).Below is an implementation plan of this approach. at the very least I'm going to wait for https://github.com/wikimedia-gadgets/types-mediawiki/pull/36 to be closed (whether merged or not) before writing any MR as there are way too many subtle changes to keep track of. As presented in the previous comment, a test implementation is available at https://github.com/Derugon/types-mediawiki/tree/split, but for easier traceability and migration process it may be better to implement this proposal in multiple steps, so we can more easily discuss each part.
JQuery
namespace, namely JQuery.Client
, JQuery.Color
, and JQuery.textSelection
,mw
(e.g. mw.Api
, mw.loader
),ApiOptions
to Options
, inside namespace mw.Api
)utils.d.ts
declaration file.export {};
),/// <reference />
,index.d.ts
file would remain the same.mediawiki
and jquery
global libraries.
./mw
to ./mediawiki
,oojs-ui
and ./jquery
types from ./mediawiki
.mediawiki
and jquery
into ResourceLoader modules.
jquery.*
or mediawiki.*
) per module,mw.config
or mw.loader
) to mediawiki
.typeRoots
and types
, users may still use include
to not have the import auto-completion be flooded with RL modules,index.d.ts
module file per module folder, which would be filled according to the associated ResourceLoader entry, see example for module mediawiki.util
below:// ResourceLoader module dependencies
// including "mediawiki.base" if there is no other mw dependencies
import "../jquery.client";
import "../mediawiki.base";
// local declaration files
import "./RegExp.d.ts";
import "./util.d.ts";
// ResourceLoader module exports
export = mw.util;
Now that the main branch is up to date with 1.42, I've reopened PR #40, for the 1st step of the above proposal.
If we are ok with it, after it is merged, I suppose we may skip step 2 (and deprecate stuff instead of removing it for now) and I'll open another PR to do steps 3, 4, and 5 at once (move stuff in submodules, while still keeping deprecated exports).
Motivation
The MediaWiki API contains various modules managed by the ResourceLoader (see Resources.php). Some ResourceLoader modules include code whose associated types are in several
.d.ts
files. For example, type declarations of scripts frommediawiki.base
can be found in:global.d.ts
,html.d.ts
,index.d.ts
,log.d.ts
,Some
d.ts
files also contain types for code loaded by different modules. For example,language.d.ts
contains type declarations for:mediawiki.language
,mediawiki.language.names
, andmediawiki.language.specialCharacters
.In general, most of MediaWiki and jQuery core modules managed by the ResourceLoader are not enabled directly when a page is loaded. By using
import "types-mediawiki"
in another package, all available type declarations are imported.In some cases, I would like to import only the modules I know are active on a page (or modules I'm going to activate dynamically, e.g. with
mw.loader.using(...)
). To do this, I could import the corresponding files (import "types-mediawiki/mw/Api"
), but there are a few issues with this:.d.ts
file names don't always match ResourceLoader module names.Proposal part 1
I suggest to change the declaration file hierarchy so each ResourceLoader module can be imported individually, e.g.:
Below are a 3 proposed implementations for this.
Alternative A
Synchronize files with MediaWiki core: create one
.d.ts
file per.js
source code file, then export one module per ResourceLoader module, maybe directly inindex.d.ts
, e.g.:(note: to help with synchronization, this list can be generated automatically from the source code)
Alternative B
Create one TS module per ResourceLoader module: gather all
.d.ts
files of a single ResourceLoader module in a directory, one directory per ResourceLoader module.Alternative C
Create one
.d.ts
file per ResourceLoader module, containing type declarations for all scripts imported by that ResourceLoader module.Proposal part 2
Currently, when using
import "types-mediawiki"
, all available modules are imported.Assuming it is possible to choose which modules to import (if desired), the base module (when using
import "types-mediawiki";
) may only export a subset of available modules, e.g.: