没有 setter 的属性的 TypeScript 接口签名。

9
我们的一个类中有一个典型的getter方法,假设如下:
class Employee implements IEmployee {
    private _fullName: string;

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

以及与之配合的界面

interface IEmployee{
     fullName: string; 
}

当使用此接口的实例时,如果我们尝试分配给fullName,编译器不会警告我们缺少setter,JS运行时只是吞咽任何赋值,并不抛出错误。是否有办法将接口成员标记为仅具有getter或仅具有setter?
我看到了this post,但它很旧了,我想知道是否有任何改进。

真的很惊讶这个问题的活动度如此之低。只读属性非常有用,也是我在 TypeScript 中尝试实现的第一个模式之一。 - gravidThoughts
2个回答

2

在Typescript中,属性现在可以有“readonly”修饰符,这将实现所需的结果。

原始答案: "最初的回答"

interface IEmployee{
    readonly fullName: string; 
}

1

这是一个有趣的问题。在 TypeScript 中,只读属性的概念与其他语言略有不同。

在许多语言中,具有getter(但没有setter)的属性如果您尝试设置该属性,则会引发编译器错误,但TypeScript不会。

该属性仍然是只读的,因为如果您尝试设置它,设置将会悄无声息地失败,并不会产生影响。

以下是一个不使用任何接口的示例:

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

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

当我使用x.name = 'Example 2';时,没有编译器警告。
如果有编译器警告,我随后会期望在接口中有一种指定只读属性的方式。但是,根据上述信息,您不能在接口上设置只读属性。
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);

这意味着您只能通过拥有获取属性值的方法(显然不能有设置属性值的方法)来强制执行只读属性。
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());

只读性在缺少 setter 的情况下已经被 JS 行为强制执行。问题在于它的静默性 - 悄悄地吞噬值。理想(并希望出现)的解决方案是允许将 TS 接口成员标记为仅具有 getter\setter。另一种选择是在缺少 getter/setter 的情况下,由转译器生成空的 getter/setter,这将简单地抛出错误(至少对于 setter,这是我们整个团队预期的行为)。最终繁琐的解决方案是,如果不需要实际的 setter,则始终手动创建一个抛出异常的 setter。 - Ivan Koshelev
“Readonlyness is pretty much enforced already by JS behavior in absence of a setter.” 是的 - 尽管通过“强制执行”,我更多地是指编译器警告、波浪形红线和某种听得见的警报。示例代码显示了设置尝试的静默丢弃。同时,使用属性访问方法是获得编译时保证,确保没有进行设置尝试的唯一方法。 - Fenton
在 GitHub 上发布了关于这个问题的问题 https://github.com/Microsoft/TypeScript/issues/814 - Ivan Koshelev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接