I have a class Client
and I want to create a new class UpdateClient
but omitting few properties of class Client
.
class Client {
constructor() {
this.clients = '';
this.client_secret = '';
}
clients: string;
client_secret: string;
}
I want class UpdateClient
to be like this
class UpdateClient {
constructor() {
this.clients = '';
}
clients: string;
}
Now, I'm sure there will be few approaches in vanilla JS by which I can get the task done, like iterating over all enumerable properties of class client
, but I don't want to that.
I want a typescript specific solution. I found Omit
type utility and it's working as expected. However, there's a small issue which I'm unable to fix.
This is the whole code snippet
class Client {
constructor() {
this.clients = '';
this.client_secret = '';
}
clients: string;
client_secret: string;
}
type T = Omit<Client, 'client_secret'>
I'm getting a type instead of a class. I want to somehow convert this type T
to the class UpdateClient
and export it. The exported property needs to be a class because the other module using this one expects a class.
I'm using typescript v3.7.5
If all you want is for UpdateClient
to be a class constructor that makes instances of Omit<Client, 'client_secret'>
, you can write it this way:
const UpdateClient: new () => Omit<Client, 'client_secret'> = Client;
The declared type new () => ...
means "a constructor which takes no arguments and produces an instance of ...". The syntax is either called a constructor signature or "new
able" and is part of the static side of a class.
The fact that the above code, assigning Client
to the variable UpdateClient
, compiles without error shows that the compiler agrees that Client
does act like a no-arg constructor of Omit<Client, 'client_secret'>
. If, for example, Client
's constructor required an argument, or if Omit<Client, 'client_secret'>
weren't a supertype of Client
, you'd get an error:
class RequiresArg {
constructor(public clients: string) { }
}
const Oops: new () => Omit<Client, 'client_secret'> = RequiresArg; // error
// Type 'typeof RequiresArg' is not assignable to type 'new () => Pick<Client, "clients">'
class NotCompatible {
clients?: number;
}
const StillOops: new () => Omit<Client, 'client_secret'> = NotCompatible; // error
// Type 'number | undefined' is not assignable to type 'string'.
Anyway, then this will work:
const c = new UpdateClient();
c.clients; // okay
c.client_secret; // error at compile time, although it does exist at runtime
Do note that even though UpdateClient
's instances are not known by the compiler to have a client_secret
property, it's still just an instance of Client
at runtime, so the property will definitely exist at runtime. If that's a problem you should probably do something completely different. But since you said Omit<...>
works for you, I guess that's not an issue.
Okay, hope that helps; good luck!