Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript Interface signature for property without setter.

We have a typical getter in one of our classes, lets say

class Employee implements IEmployee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }
}

and an interface to work with it

interface IEmployee{
     fullName: string; 
}

When working with an instance via this interface the compiler will not warn us about absence of a setter if we try to assign to fullName, and the the JS runtime simply swallows any assignment and does not throw an error. Is there any way to mark interface member as having only getter or only setter?

I've seen this post, but it is quite old, i want to know, if anything improved.

like image 310
Ivan Koshelev Avatar asked Oct 03 '14 15:10

Ivan Koshelev


2 Answers

Properties in typescript can now have 'readonly' modifier, which achieves the desired restult.

interface IEmployee{
    readonly fullName: string; 
}
like image 179
Ivan Koshelev Avatar answered Nov 15 '22 14:11

Ivan Koshelev


This is an interesting question. The concept of a readonly property is subtly different in TypeScript to other languages.

In many languages a property with a getter (but no setter) would raise a compiler error if you attempted to set the property, but TypeScript doesn't.

The property is still readonly, because it makes no difference if you attempt to set it; the set will fail silently.

Here is an example without any interfaces:

class Example {
    get name() {
        return 'Steve';
    }
}

var y = new Example();
y.name = 'Example 2';
alert(y.name);

There is no compiler warning when I use x.name = 'Example 2';.

If there was a compiler warning, I would subsequently expect there to be a way of specifying the readonly-ness of a property within an interface. As you'd expect though, given the above information, you can't set a readonly property on an interface.

interface Test {
    name: string;
}

class Example {
    get name() {
        return 'Steve';
    }
}

var x: Test = new Example();
x.name = 'Example 1';
alert(x.name);

var y = new Example();
x.name = 'Example 2';
alert(x.name);

This means you can only enforce readonly-ness by having a method to get the value of the property (and obviously no method that allows it to be set).

interface Test {
    getName: () => string;
}

class Example {
    getName() {
        return 'Steve';
    }
}

var x: Test = new Example();
//x.getName('Obviously not');
//x.getName() = 'Obviously not';
alert(x.getName());

var y = new Example();
//y.getName('Obviously not');
//y.getName() = 'Obviously not';
alert(y.getName());
like image 23
Fenton Avatar answered Nov 15 '22 14:11

Fenton