Page 1 of 1

[TypeScript] How to declare types for data fields in Model

Posted: Wed Aug 10, 2022 2:52 pm
by pmiklashevich

Hi! Could you please suggest how to declare field types in a model class when you extend Model?
I get typings error when I refer to fields as this.myField.

Property 'myField' does not exist on type 'MyModel'.

For example:

import { Model, DataFieldConfig } from '@bryntum/schedulerpro'

class PlayerModel extends Model {
  static $name = 'PlayerModel'

  static get fields(): Partial<DataFieldConfig>[] {
    // [TypeScript] Property type is missing in DataFieldConfig #5017
    // https://github.com/bryntum/support/issues/5017
    return [
      { name: 'firstName', type: 'string', dataSource: 'first_name' },
      { name: 'lastName', type: 'string', dataSource: 'last_name' },
    ]
  }

  get isPlayerModel(): boolean {
    return true
  }

  get fullName(): string {
    // TODO: think how to declare 'firstName' and 'lastName'.
    //       Property 'firstName' does not exist on type 'PlayerModel'.
    //       Property 'lastName' does not exist on type 'PlayerModel'.
    return `${this.firstName} ${this.lastName}`
  }

  set fullName(name: string) {
    const [firstName, ...otherNames] = name.split(' ')
    const lastName = otherNames.join(' ')

this.firstName = firstName
this.lastName = lastName
  }
}

export default PlayerModel
Снимок экрана 2022-08-10 в 15.49.30.png
Снимок экрана 2022-08-10 в 15.49.30.png (288.14 KiB) Viewed 740 times

Thanks in advance!


Re: [TypeScript] How to declare types for data fields in Model

Posted: Thu Aug 11, 2022 9:35 am
by saki

Pavel, you can add:

    public firstName = '';
    public lastName = '';

to the PlayerModel class. That will resolve the TS errors but I haven't tested whether it'll actually work in the app. I see no reason why it shouldn't, though. Let us please know if it helped.


Re: [TypeScript] How to declare types for data fields in Model

Posted: Thu Aug 11, 2022 10:09 am
by pmiklashevich

Hello Saki!

It doesn't work. When you specify classes like this, you give it priority over the real fields. So the grid has empty rows.

  public firstName = 'Peter';
  public lastName = 'Parker';

The value you set is spread around the grid

Снимок экрана 2022-08-11 в 11.03.22.png
Снимок экрана 2022-08-11 в 11.03.22.png (29.25 KiB) Viewed 708 times

Re: [TypeScript] How to declare types for data fields in Model

Posted: Thu Aug 11, 2022 10:12 am
by saki

I see. Let's try to be less forceful then:

    public firstName!: string;
    public lastName!: string;

Mind the exclamation mark.


Re: [TypeScript] How to declare types for data fields in Model

Posted: Fri Aug 19, 2022 4:53 pm
by pmiklashevich

Hello Saki,

This approach doesn't work either. The values are undefined. Please get one of your examples up and running and try it yourself. Need to come up with a proper solution to be able to define types for new fields. I would appreciate your help on this.

Thanks!


Re: [TypeScript] How to declare types for data fields in Model

Posted: Sat Aug 20, 2022 8:20 pm
by pmiklashevich

Hi again! I think I have found a solution. Please take a look and let me know what you think. If you find it useful please update the docs accordingly.

I was inspired by lib.d.ts docs. It shows how to customise Window object. I also found a reference to TS docs. Trying to understand the difference between "type" and "interface" declaration, I found the following StackOverflow thread. The answer shows all possible combinations to extend interfaces/types. Also the difference is highlighted in official TS docs.

So, here is the solution. You can see it solves two problems. First, it adds declaration to the fields described in the "fields" static getter. Second, it adds missing "type" property to the DataFieldConfig type (there was another report to add the "type" https://github.com/bryntum/support/issues/5017). But now this can be a workaround for those who spot a type is missing. Previously the suggestion was to use ts-ignore which actually masked the problem.

import { Model, DataFieldConfig } from '@bryntum/schedulerpro'

// Implicitly adds new fields to an existing interface (mixes types into PlayerModel extending Model types)
interface PlayerModel {
  firstName: string;
  lastName: string;
}

// Explicitly extends Bryntum types and adds missing types
interface DataFieldConfigExtension extends DataFieldConfig {
  type: string;
}

class PlayerModel extends Model {
  static $name = 'PlayerModel'

  static get fields(): Partial<DataFieldConfigExtension>[] {
    return [
      { name: 'firstName', type: 'string', dataSource: 'first_name' },
      { name: 'lastName', type: 'string', dataSource: 'last_name' },
    ]
  }

  get isPlayerModel(): boolean {
    return true
  }

  get fullName(): string {
    return `${this.firstName} ${this.lastName}`
  }

  set fullName(name: string) {
    const [firstName, ...otherNames] = name.split(' ')
    const lastName = otherNames.join(' ')

this.firstName = firstName
this.lastName = lastName
  }
}

export default PlayerModel

See, no TS errors in IDE:

Screen Shot 2022-08-20 at 21.03.23.png
Screen Shot 2022-08-20 at 21.03.23.png (305.74 KiB) Viewed 636 times

Best regards!


Re: [TypeScript] How to declare types for data fields in Model

Posted: Tue Aug 23, 2022 12:52 pm
by sergey.maltsev

Hi, Pavel.

Yes you are right.
We actually have pretty much the same code in our Gantt Angular Advanced demo in Gantt/examples/frameworks/angular/advanced/src/app/lib/Task.js

I've created this issue to add some clarification for this approach to Docs guides.
https://github.com/bryntum/support/issues/5106


Re: [TypeScript] How to declare types for data fields in Model

Posted: Tue Aug 23, 2022 9:42 pm
by pmiklashevich

Hi Sergey! Thanks for confirming I'm right!
Cheers!