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?

2
  • So you want the generated type to expect id, _createdAt and _updatedAt properties in this case ? Commented Jun 17, 2021 at 9:00
  • @FrankBessou yes Commented Jun 18, 2021 at 1:48

2 Answers 2

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>> 
Sign up to request clarification or add additional context in comments.

2 Comments

can you explain ` (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? A : B;` part a little bit for me? thanks
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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.