-
-
Notifications
You must be signed in to change notification settings - Fork 285
feat: typed storages support #826
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
base: main
Are you sure you want to change the base?
Conversation
@mrousavy I look forward to your feedback! Please let me know if I can update the Readme. |
I appreciate the PR, but you added a package-lock.json which clearly can't be right. MMKV uses Bun or Yarn. Also, I don't think this should be patched into MMKV.ts, this should be an added interface ontop. |
@mrousavy good catch about As for this:
I'm not quite sure how the same functionality can be achieved without touching |
You just provide a thin wrapper that only does types. Your implementation doesn't do anything else, no JS logic as far as I can see. So users would call |
@mrousavy yes, my implementation does not change JS logic. But it looked to me that introducing a new class is a bit redundant comparing to adding an optional generic type to the existing one ( PS: Also, I moved types tests to a separate directory and added them to the code-checks pipeline. Could you please check? |
Looks reasonable to me, existing users do not need to change anything Using more specific types is opt-in via generics |
@mrousavy just a friendly ping here 🙂 |
@mrousavy Looks good to me too. |
@mrousavy just a kindly reminder about this PR :) |
@@ -127,7 +136,9 @@ export class MMKV implements MMKVInterface { | |||
}; | |||
} | |||
|
|||
addOnValueChangedListener(onValueChanged: (key: string) => void): Listener { | |||
addOnValueChangedListener( | |||
onValueChanged: (key: keyof TStorage) => void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This right here is problematic since it is technically not true. The user can create a new MMKV instance that is not typed but has the same key, set a value that is not a value of keyof TStorage
, and then the onValueChanged
listener will be called with a value that is within the typescript types.
I guess it's an edge case, but should still be considered. Maybe we keep this string
? People will probably complain if it's string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mrousavy I'm not sure this changes anything technically, since this method belongs to a storage instance. For a typed storage instance, it will suggest one of its keys, while for an untyped instance, the keys will have the string
type (i.e., it will work as before).
I've added a test that demonstrates this—let me know if I misunderstood anything.
I gotta be honest I'm still pretty torn between either merging this or having the user be responsible for this. There's a few cases where the type safety just isn't guaranteed. After all, it's a storage - it can be anything if written to from elsewhere (e.g. from an untyped MMKV storage, from a previous version where the user specified different types, or from native). I feel like this just increases the maintenance layer for me - people will find bugs in the type system here and complain in issues. |
If it helps, I implemented something pretty similar for storage in the apps I've been working on, but it uses zod validation to enforce the storage values at runtime + a primitive migrations system, to address the whole type 'assumption' problem.
Probably not able to share what we're using as it's a bit tightly coupled with our stuff, but I'll maybe look into throwing together a thin wrapping library (since this seems to be beyond the scope of this project) using https://github.com/standard-schema/standard-schema given the interest is there. |
@mrousavy Thank you for taking a look! Thoughts? @NathanP-7West Thank you for your comment! |
@mrousavy In the last two commits, I slightly tightened some type checks for default (non-typed) storage and added a few more tests to demonstrate that non-typed storage types aren't affected and continue to work correctly. So all comments seems to be resolved. Looking forward to your feedback! |
@mrousavy just a kind reminder that this PR waits for your attention |
Changes for #815
Changes
tsd
Usage
More examples of correct and incorrect use-cases can be found in types tests file
package/src/__types_tests__/mmkv.test-d.ts