0

Say I have a class looking like below

class Model {
  id: string;
  _createdAt: string;
  _updatedAt: string;

  constructor(params: // currently I am doing Partial<Model> but I would like params to
// only contain the variables at the top excluding any methods/getters/setters){
    this.id = params.id;
    this._createdAt = params.createdAt;
    this._updatedAt = params.updatedAt;
  }

  get createdAt{
    return moment(this._createdAt);
  }

  get updatedAt{
    return moment(this._updatedAt);
  }
}

I would like to be able to construct a typescript type/interface of an object type that reflects the variables in the Model. I am currently doing params: Partial<Model> but this assumes that params is going to contain all the properties of Model class. However, I want only the variables to be the keys of the interface. Is there a way of doing this without having to define all properties of interface myself?

forJ
  • 4,309
  • 6
  • 34
  • 60

2 Answers2

2

Perhaps the read-only nature of the getter attribute can be used to exclude him

enter image description here

class Model {
  id="";
  _createdAt="";
  _updatedAt="";

  constructor(params:any ){
    this.id = params.id;
    this._createdAt = params.createdAt;
    this._updatedAt = params.updatedAt;
  }

  get createdAt(){
    return moment(this._createdAt);
  }

  get updatedAt(){
    return moment(this._updatedAt);
  }
}


type IfEquals<X, Y, A=X, B=never> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? A : B;

type WritableKeys<T> = {
  [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P>
}[keyof T];






type a  = Pick<Model,WritableKeys<Model>> 
崮生1
  • 46
  • 1
  • 4
  • can you explain ` (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? A : B;` part a little bit for me? thanks – forJ Jun 18 '21 at 01:48
  • @forJ https://stackoverflow.com/questions/49579094/typescript-conditional-types-filter-out-readonly-properties-pick-only-requir – 崮生1 Jun 19 '21 at 13:08
1

I,

I think that the solution of 崮生1 is really great and correspond to your need. I just add a little change in is code to avoid the methods in the class :

type IfEquals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
    ? 1
    : 2
    ? 'false'
    : 'true'

type WritableKeys<T> = {
    [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }> extends 'true'
        ? never
        : T[P] extends Function
        ? never
        : P
}[keyof T]
Ken La
  • 161
  • 7