Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish Typescript declaration file #23

Closed
ttmarek opened this issue Mar 4, 2018 · 15 comments
Closed

Publish Typescript declaration file #23

ttmarek opened this issue Mar 4, 2018 · 15 comments

Comments

@ttmarek
Copy link

ttmarek commented Mar 4, 2018

Hi @dumbmatter.

Thanks for such an awesome module! I'm currently using this for some tests in a library of mine that I'm transitioning from JavaScript to Typescript. I was wondering if it would be possible to push a new release out with some Typescript declaration files. It shouldn't be too hard to do since you're using Typescript yourself. Just setting declaration: true and removing allowJs: true in tsconfig.json should do the trick.

@dumbmatter
Copy link
Owner

Thanks for the suggestion!

Is it actually that simple? I remember being very confused by how TypeScript modules work, and that is both why the lib folder is so ugly and why there are no exported types. If you try it and it works, I'll happily add it. But even if it works for the main export (or whatever the hell it's called), I am concerned it wouldn't work with the exported classes in lib. Basically my goal is to maintain backwards compatibility for the API, so var IDBKeyRange = require("fake-indexeddb/lib/FDBKeyRange"); continues to work, but I couldn't get TypeScript to do that in a reasonable fashion.

@mcshaz
Copy link

mcshaz commented Mar 28, 2019

even if it just exported the typescript interfaces IDBFactory and IDBKeyRange (from the typescript dom library) it would be fantastic. maintaining backward compatability is fantastic, but it would be great if a package like this could support the ES6 module standard.

@dumbmatter
Copy link
Owner

I'd accept a PR that exports all the classes as named exports, and fakeIndexedDB as the default export. However I'd also want to maintain backwards compatibility, which should be possible in theory. Last time I tried, I couldn't figure out how to get it to work without making CommonJS users add .default after importing, which is not backwards compatible. Maybe things are better now than they were a couple years ago... back then, TypeScript compatibility with ES6 modules seemed like it was implemented really stupidly and confusingly.

@hhimanshu
Copy link

Does the typescript declaration exist?

@Richifg
Copy link

Richifg commented Nov 20, 2020

Hello, I just createad a PR which adds declaration files to the build folder so it shouldn't affect backwards compatibility.

@clintharris
Copy link

Hi, I'd also like to offer PR #58 as a possible solution.

It differs a bit from Ricardo's PR in that it writes .d.ts files alongside the legacy API "proxy" modules in lib/ so that folks can keep using the same paths:

 |-package.json
 |-lib
 | |-FDBDatabase.js
 | |-FDBDatabase.d.ts ✨
 | |-FDBIndex.js
 | |-FDBIndex.d.ts ✨

This seems to work fine in Typescript, for example:

import FDBFactory from 'fake-indexeddb/lib/FDBFactory'

const factory = new FDBFactory()

I published my fork with these changes if anyone wants to kick the tires:

npm install -D @clintharris/fake-indexeddb

@dumbmatter
Copy link
Owner

Question for @clintharris and @Richifg (and anyone else who wants to chime in)...

Does it actually make sense to export types like this? Or should we have manually-written .d.ts file that just says "fake-indexeddb behaves just like the normal IndexedDB types included with TypeScript"?

Because in the case where they differ for some reason, why would anyone prefer the fake-indexeddb version? Since your application code is presumably written using the built-in TypeScript types.

Or should fake-indexeddb itself be modified to explicitly implement the interfaces from the built-in TypeScript types? I feel like that might be the real solution, and the least likely to cause problems down the road.

Basically my concern is releasing this and breaking a bunch of people's builds due to some mundane type difference...

@clintharris
Copy link

I agree that it seems like having fake-indexedDB export objects that are typed using the standard, Typescript-provided IndexedDB types is the best long-term solution. With, maybe, occasional exceptions were it to offer custom API feature for doing non-standard things (e.g., a convenience function for resetting the entire state of fiDB, or getting access to the real IndexedDB globals, etc.). 🙂

And you have a good point about something like PRs #57 and #58 basically introducing "custom" types that could cause problems in the future--not necessarily if they were released tomorrow, but in a following release if the project were to then start exporting standard API types. In other words, if the project started exporting FDB* types this week, and IDB* types next week, that's a breaking API change.

@weilbith
Copy link

Okay, so after all: how do I solve this issue that TypeScript gives me an error that it has no declaration file for it?

@dumbmatter
Copy link
Owner

// @ts-ignore
import "fake-indexeddb/auto";

@Dahaden
Copy link

Dahaden commented Jul 12, 2021

Just wondering could we mitigate some of the issues if we were to export types as an OR between the FDB* types and IDB*?

This way users could use any common APIs easily but anything like FDBTransaction#commit or other methods that are defined in FDB* only then users would have to check at that point?

EDIT: This is how I imagine it typescript playground link thats very long

@dumbmatter
Copy link
Owner

@Dahaden thanks for the suggestion and the prototype code!

The problem I worry about with this is if you're passing around IndexedDB variables in your application code, that code shouldn't have to care that fake-indexeddb exists, so any difference in types between fake-indexeddb and IndexedDB could result in a lot of false positive TypeScript errors. Extension of your example.

Ultimately I think there's not much to gain by doing anything other than using the built-in TypeScript IndexedDB types. Anything in fake-indexeddb that's not in real IndexedDB is not part of the public API currently anyway. (For your example, IDBTransaction.commit actually does exist.) If eventually stuff is added to the public API like #50 or #51, then the fake-indexeddb types could just be like IDBFactory & { myAPI: () => void }.

I'm going to try to do a new release containing TypeScript types and maybe also moving to ES modules if that doesn't cause too many issues. Working on that now in the v4 branch: https://github.com/dumbmatter/fakeIndexedDB/tree/v4

@dumbmatter
Copy link
Owner

I published a beta if anyone wants to try it, seems to work fine for me. https://www.npmjs.com/package/fake-indexeddb/v/4.0.0-beta.1

@icorbrey
Copy link

If it helps anyone, I'm currently working around this by just wrapping FDBFactory with a getter:

import FDBFactory from 'fake-indexeddb'

export const getDatabase = () =>
    new FDBFactory() as typeof indexedDB

@dumbmatter
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants