Repository navigation
Add firefox-webext-browser types for FireFox WebExtension Development - #21749
Conversation
|
types/firefox-webext-browser/index.d.ts Checklist
|
namespace foo.bar {
export function default(): void;
}is illegal, but is equivalent to the legal declaration namespace foo {
export const bar: {
default(): void;
}
}There are certain combinations that can't be expressed that way; see microsoft/TypeScript#9846 |
|
this is legal: declare namespace foo.bar {
function _default(): void;
export { _default as default };
} |
- Rename generated enums not present in schemas so that they have an underscore first in hopes of it being seen as private (and therefore not available to code) - Fix browser.bookmarks.import/export as per PR comments
|
@RyanCavanaugh Thanks for those answers, I've gone ahead and created a repository for the generator and put it in a comment. Should be good for review now. |
rpl
left a comment
There was a problem hiding this comment.
@bomjacob hey! this is amazing, thank you a lot for getting this started \o/
I had no previous experience with typescript until now, and so it has been also a good opportunity to look into it for my first time ;-)
I have not been able to look too deep into all the API namespaces yet, but I've added an initial round of comments that could be already useful.
| stdio = "stdio" | ||
| } | ||
|
|
||
| enum _NativeManifestType { |
There was a problem hiding this comment.
This _NativeManifestType has been declared two times (probably because of how the generator script from https://github.com/bomjacob/definitelytyped-firefox-webext-browser is handling this schema file https://searchfox.org/mozilla-central/rev/0b613c3887789f7786cd3131dfe9648398f4a6ac/toolkit/components/extensions/schemas/native_manifest.json#25,55).
But this enum is only used in the NativeManifest type which is not exposed to any API method (iirc we just use it internally to validate this kind of manifest JSON files, but they are not used in any of the APIs exposed to the extension code), and so I think that the generator script could just ignore them when parsing the schema files and/or omit their types from the generated typescript type definitions.
There was a problem hiding this comment.
I've chosen just to omit the NativeManifest type for now
| // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped | ||
| // TypeScript Version: 2.4 | ||
| // Generated using script at github.com/bomjacob/definitelytyped-firefox-webext-browser | ||
|
|
There was a problem hiding this comment.
it could be probably reasonable to also define browser as a property of the Window object, like the existent chrome types from this repo are doing:
DefinitelyTyped/types/chrome/index.d.ts
Lines 9 to 14 in 0128360
I'm not 100% sure if it is needed to be able to define the browser property inside the Window interface, but it is worth to mention that chrome tsconfig.json also include "dom" in the libs property:
DefinitelyTyped/types/chrome/tsconfig.json
Lines 4 to 7 in 0128360
| const onAlarm: EventListener<(name: Alarm) => void>; | ||
| } | ||
|
|
||
| declare namespace browser.manifest { |
There was a problem hiding this comment.
There is no browser.namespace API namespace exposed to the extensions code, but some of this types are used in other APIs, it could be nice if it is possible to include the needed types definitions without an explicit browser.manifest namespace, which I guess would be suggested in auto-completion because it exists in these types definitions, am I right? or, if this namespace can't be easily removed, another option could be to rename it to browser._manifest)
There was a problem hiding this comment.
I assume you mean that there is no browser.manifest namespace exposed?
I've renamed it to _manifest for now...
I've tried to see if there is any way to make some functions or types "private" so that they wouldn't show up in autocomplete, but I've found nothing so far.
| // TypeScript Version: 2.4 | ||
| // Generated using script at github.com/bomjacob/definitelytyped-firefox-webext-browser | ||
|
|
||
| interface EventListener<T extends (...args: any[]) => any> { |
There was a problem hiding this comment.
Ah, this is very nice!
I think that it would be better to rename it, e.g. WebExtEventListener, so that its name doesn't clash with the EventListener type defined as part of "dom" (and this is also shown when running the linting once you include "dom" in the tsconfig.json libs)
| }; | ||
| } | ||
|
|
||
| type KeyName = string | string | string; |
There was a problem hiding this comment.
I guess that the generator scripts generates this type from https://searchfox.org/mozilla-central/rev/0b613c3887789f7786cd3131dfe9648398f4a6ac/browser/components/extensions/schemas/commands.json#9-25
which contains 3 possible patterns that a command included in the manifest.json should match (it should match 1 of them).
An option to fix it in the generator script could be to clean up the results that we get from processing the "choices" in the schemas, by removing any type that has been included more than ones in the result.
| type?: ViewType; | ||
| windowId?: number; | ||
| tabId?: number; | ||
| }): object/*Window*/[]; |
There was a problem hiding this comment.
object could be probably be Window here if "dom" is included in tsconfig.json.
|
|
||
| function getPlatformInfo(): Promise<PlatformInfo>; | ||
|
|
||
| function getPackageDirectoryEntry(): Promise<object/*DirectoryEntry*/>; |
There was a problem hiding this comment.
getPackageDirectoryEntry is not supported on Firefox:
In general every API method, type and property which is marked as "unsupported": true in the schema, it is something that is available in the original Chrome schema file but it is not in the Firefox implementation.
it could be reasonable to keep this "unsupported" property into account in the generator script, one option can be to omit what is unsupported from the final generated types.
Another option could be to make them optional properties in the generated typescript type definitions, so that the "typescript type checking" would raise an error if the "unsupported" method (or property) is used without doing some kind of "feature detection" (e.g. this is also true for the Firefox for Android schema, which is some cases doesn't support yet all the features supported in Firefox for Desktop, and so in the Firefox for Android schema some property may be marked as unsupported, https://searchfox.org/mozilla-central/source/mobile/android/components/extensions/schemas).
There was a problem hiding this comment.
Okay, I live the 2nd approch the most, so I've made the generator script treat unsupported as optional.
It's working for properties, functions and events, I am unsure if we can make class, enum, type and interface optional though.
| typed = "typed", | ||
| auto_bookmark = "auto_bookmark", | ||
| auto_subframe = "auto_subframe", | ||
| manual_subframe = "manual_subfram |
There was a problem hiding this comment.
browser.contextMenus should also contain the API methods provided by browser.menus (the related API schema file is probably the only one that uses an "$import" property, which imports the content of the "menus" namespace into the "contextMenus" namespace)
| typed = "typed", | ||
| auto_bookmark = "auto_bookmark", | ||
| auto_subframe = "auto_subframe", | ||
| manual_subframe = "manual_subfram |
There was a problem hiding this comment.
browser.menusInternal is not not exposed to the extension code as a valid API namespace, but the OnClickData type defined here seems to be needed because it is used in the browser.menu.update API method
(to be fair, the two menu.OnClickData and menusInternal.OnClickData types seems to be similar but not in sync in the Firefox API schema, I'm going to take a deeper look to how we are using them internally).
There was a problem hiding this comment.
So would an okay solution for now be to maybe rename menusInternal to _menusInternal?
| @@ -0,0 +1,2 @@ | |||
| // No tests yet | |||
| true; | |||
There was a problem hiding this comment.
While I was experimenting a bit with this (I had not previous experience with typescript or DefinitelyTyped until now), I started to put something in this file, it looks a pretty useful way to test the generated types (especially if you want to be sure that the types are still generated correctly while tweaking the generator script), here is some example tests that I added into it:
browser.nonexistentNS.unknownMethod(); // $ExpectError
// Various API types tests
browser.runtime.getManifest(); // $ExpectType ManifestType
See commit history at jsmnbom/definitelytyped-firefox-webext-browser@71548e2...b7e3c09 for full list of changes.
|
@bomjacob The DefinitelyTyped team prefers fast iteration. If any modification is required according to later review, it is desired to create a new pull request. AFAIK. |
template
Not tested using typescript code, but the types have been tested using WebStorm's type checking engine on various javascript snippets
Think i did everything properly
npm run lint package-name(ortscif notslint.jsonis present).Lint passes, note the rules in tslint.json though
If adding a new definition:
dts-gen --dt, not by basing it on an existing project.tslint.jsonshould be present, andtsconfig.jsonshould havenoImplicitAny,noImplicitThis,strictNullChecks, andstrictFunctionTypesset totrue.questions