Currently there's unofficial, likely unmaintained, and out-of-date TypeScript definitions published via https://github.com/DefinitelyTyped/DefinitelyTyped for the pdfjs-dist
library; see https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/pdfjs-dist
Now that we, from version 2.6.347
, are shipping official TypeScript definitions through https://github.com/mozilla/pdfjs-dist, it'd be a good idea to submit a PR to DefinitelyTyped to remove its TypeScript definitions; see https://github.com/DefinitelyTyped/DefinitelyTyped#removing-a-package
The official TS definitions bundled in 2.6.347, while much appreciated, only include bindings for the top-level API and therefore lack many of the useful types currently exposed by the DefinitelyTyped definitions, such as:
PDFPageProxy
PDFDocumentProxy
PDFRenderTask
PDFDocumentLoadingTask
It's possible to access these types through the official definitions by using complex sequences of type operations, e.g.:
type PDFDocumentProxyPromise = ReturnType<typeof getDocument>['promise']
type PDFDocumentProxy = PDFDocumentProxyPromise extends Promise<infer U> ? U : never
However, this is inconvenient and also unconventional within the TypeScript ecosystem. Type definitions for libraries usually export typings for important objects/classes (without exporting their values).
Would you consider exposing these types in the official type definitions before removing the typings from DefinitelyTyped?
I would say so since I think they are all part of the public API; see for example https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L2966-L2967. The TypeScript definitions are generated from our JSDoc comments because PDF.js itself is not a TypeScript project, so any improvements for the typings are much appreciated from the community who have already helped a lot to get the current typings in place.
I would say so since I think they are all part of the public API;
Well, the public API is actually only https://github.com/mozilla/pdf.js/blob/master/src/pdf.js :-)
see for example https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L2966-L2967
That was exposed there for the unit-tests specifically, as far as I remember.
[...] because PDF.js itself is not a TypeScript project, so any improvements for the typings are much appreciated
I do believe that we said, when landing the TypeScript definitions, that it'll be up to the TypeScript users to help maintain the definitions. (Since as mentioned this is a JavaScript project, and the PDF.js contributors cannot be assumed to know TypeScript.)
Generally speaking: I'm not crazy about the idea of simply exposing those properties in the public API unconditionally, since it's objects that users should never call/initialize manually.
It would seem preferably, as far as I can tell, if there's a way of exposing them in the TypeScript definitions without having to extend the official API in the process.
D'oh, I looked at the wrong file indeed. I think the question arose from the observation that the API can return those types, and the TypeScript definitions are used to indicate the type of return value from our API so it's clear how to interact with it. If we were to expose those types in the definitions (using JSDoc comments) that wouldn't change the API itself I think. The objects themselves cannot be initialized since we don't export those, but the TypeScript definitions will then contain the description of those objects returned from the API.
We're indeed open to community improvements in this regard since the community also knows best what would fit their needs and how to test this.
if there's a way of exposing those them in the TypeScript definitions without having to extend the official API in the process
Yes, that should be possible, and it aligns with the TypeScript ecosystem in general. Regardless of whether a library is written in JS or TS, its typings will often expose some internal types in addition to types for the top-level API. This is useful when passing around values that get _produced_ by the library's API. Here's a contrived example; without the PDFDocumentProxy
type exported, it would be difficult to type the getNumPagesOfDocument
function correctly:
import {getDocument, PDFDocumentProxy} from 'pdfjs-dist'
function getNumPagesOfDocument(doc: PDFDocumentProxy): number {
return doc.numPages
}
async function getNumPagesOfFile(file: File): Promise<number> {
const doc = await getDocument(file).promise
return getNumPagesOfDocument(doc)
}
Note that getDocument
is a value whereas PDFDocumentProxy
is a type. TypeScript will not permit the latter to be used as a value. All references to it will be removed when the code is compiled to JS.
Anyway, I'm not sure when I'll find time for this, but, if someone else doesn't beat me to it, I'll look into how the pdfjs type generation currently works and see if there's a simple to way to manually list a few types that should be exported in addition to those of the top-level runtime API. Thanks for being open to the change!
For PDF.js v2.6.347, you can import them with the following:
import type {PDFDocumentProxy, PDFPageProxy} from 'pdfjs-dist/types/display/api'
We can export the types, not actual classes, at pdf.d.ts
with the following JSDoc.
diff --git a/src/pdf.js b/src/pdf.js
index c6a6d1338..4ef9d30b7 100644
--- a/src/pdf.js
+++ b/src/pdf.js
@@ -13,6 +13,11 @@
* limitations under the License.
*/
+/**
+ * @typedef {import("./display/api").PDFDocumentProxy} PDFDocumentProxy
+ * @typedef {import("./display/api").PDFPageProxy} PDFPageProxy
+ */
+
import {
addLinkAttributes,
getFilenameFromUrl,
Then the generated build/types/pdf.d.ts
begins with the following lines:
export type PDFDocumentProxy = import("./display/api.js").PDFDocumentProxy;
export type PDFPageProxy = import("./display/api.js").PDFPageProxy;
To provide some additonal context on the typings discussion, the example at https://github.com/mozilla/pdf.js/blob/master/examples/components/simpleviewer.js, uses the EventBus, PDFFindController, PDFLinkService, PDFViewer - all of which are exported by pdfjs-dist/web/pdf_viewer.js
, but do not have typings defined in pdfjs-dist/types/*
.