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

TS: field @name restriction when data is an EmberChangeset #211

Open
bartocc opened this issue Nov 29, 2023 · 1 comment
Open

TS: field @name restriction when data is an EmberChangeset #211

bartocc opened this issue Nov 29, 2023 · 1 comment

Comments

@bartocc
Copy link

bartocc commented Nov 29, 2023

When the data passed to HeadlessForm is a POJO, the field's @name is required to be a key of this POJO.
But when the data is an EmberChangeset, @name only needs to be a string.

Is this a limitation of HeadlessForm, or do I need to do some TS setup to achieve the same behaviour ?

// foo.gts
import Component from '@glimmer/component';
import { HeadlessForm } from 'ember-headless-form';
import { Changeset, EmberChangeset } from 'ember-changeset';
import lookupValidator from "ember-changeset-validations";

interface MyData {
  username?: string;
  email?: string
}

export default Foo extends Component {
  get data: MyData {
    return {}
  }

  get changeset(): EmberChangeset {
    return Changeset(this.data, lookupValidator({}), {});
  }

  <template>
    <HeadlessForm @data={{this.data}} as |form|>
      {{!-- Glint will emit an error here --}}
      <form.Field @name='an-invalid-name' as |f|>
        <f.Input />
      </form.Field>
    </HeadlessForm>

    <HeadlessForm @data={{this.changeset}} as |form|>
      {{!-- Glint will NOT emit an error here --}}
      <form.Field @name='an-invalid-name' as |f|>
        <f.Input />
      </form.Field>
    </HeadlessForm>

  </template>
}
@bartocc
Copy link
Author

bartocc commented Dec 1, 2023

The workaround I have found for the time being is to cast the changeset to the type of its underlying data. This brings back the @name argument type checking, but poses another issue when using validation on the form.

This is what I do

// foo.gts
import Component from '@glimmer/component';
import { HeadlessForm } from 'ember-headless-form';
import { Changeset, EmberChangeset } from 'ember-changeset';
import lookupValidator from "ember-changeset-validations";
import { validateChangeset } from 'ember-headless-form-changeset';
import { FormValidateCallback } from 'ember-headless-form';

interface MyData {
  username?: string;
  email?: string
}

export default Foo extends Component {
  get data: MyData {
    return {}
  }

  get changeset() {
    return Changeset(this.data, lookupValidator({}), {}) as MyData;
  }

  validateChangeset() {
    return validateChangeset() as unknown as FormValidateCallback<MyData>;
  }

  <template>
    <HeadlessForm
      @data={{this.changeset}}
      
      {{!-- typeof validateChangeset imported from "ember-headless-form-changeset" is FormValidateCallback<EmberChangeset>, while "@validate" expects "FormValidateCallback<MyData>" --}}
      @validate={{(this.validateChangeset)}}

      as |form|
    >
      {{!-- @glint-expect-error "an-invalid-name" is not `keyof MyData & string` --}}
      <form.Field @name='an-invalid-name' as |f|>
        <f.Input />
      </form.Field>
    </HeadlessForm>
  </template>
}

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

1 participant