Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to write a a setter for an optional propery in TypeScript which only allows to set a non-empty value?

I’m trying to make an optional property in a TS class and create a setter and a getter for it. It is implied that the property can only be set once, so I’m trying to do something like this:

private _signer?: Signer
get signer(): Signer | undefined { return this._signer }
set signer(signer: Signer) {
    if(!this.validateSignerSecret(signer)) throw Error("Invalid signer, won't set")
    if(!this.signer) {
        this._signer = signer;
        return;
    }
    if(JSON.stringify(this.signer) !== JSON.stringify(secret)) throw Error("Another signer is set already, won't update")
}

However, TS copmlains that

The return type of a ‘get’ accessor must be assignable to its ‘set’ accessor type
Type ‘undefined’ is not assignable to type ‘Signer’

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I can change this to

set signer(signer: Signer | undefined) {

but it’s not what I really need: I’d like to only allow to set a non-empty Signer while the getter can return undefined.

Can I somehow keep the prop optional and allow to set only non-empty one?

>Solution :

Unfortunately, that is not supported. It used to be that getters and setters had to operate on exactly the same type. They relaxed that in this change, but they deliberately made it so that the getter type must be assignable to the setter type. They were aware that it made cases like yours not work.

From the linked page (emphasis added):

Restrictions

As a conservative implementation, a few restrictions are in place.

First, the type of the getter must be assignable to the type of the setter. In other words, the assignment

obj.x = obj.x;

must be legal assuming obj.x is writable at all.

This restriction closes off a certain set of use cases for properties that start out "uninitialized" (usually null/undefined) but then only want "initalizing" assignments to occur. We’ll continue to examine these to see if those use cases are prevelant enough to warrant opening this up more.

These prevent novel unsoundness from occurring and makes this feature unimpactful from a type relational perspective, which limits its risk.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading