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

Issue

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’

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.

Answered By – Nicholas Tower

Answer Checked By – Mildred Charles (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *