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

Changeset types should be generic #173

Open
vlascik opened this issue May 31, 2022 · 4 comments
Open

Changeset types should be generic #173

vlascik opened this issue May 31, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@vlascik
Copy link

vlascik commented May 31, 2022

It would help the usability of changesets in Typescript if types for changesets were generic, e.g. BufferedChangeset<UserModel>, that way we would have the proper type safety and wouldn't have to rely on type casting constantly.

@snewcomer
Copy link
Collaborator

@vlascik 👋 I might need a little help in understanding a few points. So forgive me for a sec. The return value of stamping out a changeset is a Proxy. Do you see any problems with that?

@vlascik
Copy link
Author

vlascik commented May 31, 2022

Right, I imagine typing proxies could be an issue (never tried it), but seems that people have come up with some workarounds (e.g. here https://stackoverflow.com/questions/59390026/how-to-use-es6-proxy-in-typescript). Can you maybe try to flesh it out, and if you have issues maybe we can summon the gods of typescript at #topic-typescript? :D

@bakerac4
Copy link

bakerac4 commented Nov 4, 2022

  1. I was just coming here to add an issue like this, so Im glad Im not the only one.
  2. @vlascik I use this in our validation addon built on ember-changeset/ember-changeset validations and it works fairly well. Obviously doesn't provide even close to property type safety but for most use cases thats all we need it for.

EDIT: Im actually working on improving this as we speak. Here is the current version.

export type ModelAttributes<T extends Model> = Pick<T, Exclude<keyof T, keyof Model>>;
export type ModelProperties<T extends Model> = Readonly<Pick<T, Exclude<keyof T, keyof ModelAttributes<T>>>>;
export type ChangesetAttributes<T> = T extends Model ? ModelAttributes<T> & ModelProperties<T> : T;
export type GenericChangeset<T> = BufferedChangeset & ChangesetAttributes<T> & { data: T };

@miguelcobain
Copy link

@bakerac4 those types were a great help! Thank you.

For reference, this is what I ended up with in my types/index.d.ts:

// fix changeset types
// taken from https://github.com/validated-changeset/validated-changeset/issues/173
import type Model from '@ember-data/model';
import type { Changeset } from 'ember-changeset';

export type ModelAttributes<T extends Model> = Pick<T, Exclude<keyof T, keyof Model>>;
export type ModelProperties<T extends Model> = Readonly<Pick<T, Exclude<keyof T, keyof ModelAttributes<T>>>>;
export type ChangesetAttributes<T> = T extends Model ? ModelAttributes<T> & ModelProperties<T> : T;
export type BufferedChangeset = ReturnType<typeof Changeset>;
export type GenericChangeset<T> = BufferedChangeset & ChangesetAttributes<T> & { data: T };

and then using it in a component

import { Changeset } from 'ember-changeset';

import type MyModel from 'my-app/models/my-model';
import type { GenericChangeset } from 'index';

class EditModel extends Component<PropertyGeneralSignature> {
  changeset = Changeset(this.args.myModel) as GenericChangeset<MyModel>;

would be great if ember-changeset could have this return type instead.

What do you think @snewcomer ?

@SergeAstapov SergeAstapov added the enhancement New feature or request label Oct 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants