网站搜索

在 TypeScript 声明文件中可以有 getters 和 setters 吗?


我在声明文件上遇到了问题。我尝试为 openUi 框架编写 d.ts 文件。他们对属性使用 get() 和 set(var) 语法。

在 JS 中,我会有以下设置:

sap.ui.getCore().attachInit(function () {
    var text = new sap.m.Text();
    text.setText("Hello World!"); // sets the text property
    text.placeAt("content", 0);
});

在 TypeScript 中,我希望拥有如下的 getter 和 setter 语法:

var textcontrol = new sap.m.Text();
var textcontrol.Text = "Hello World"; // Sets the text property in typescript.
var text = textControl.Text; // Gets the text in typescript.

这应该编译成我 JS 输出中的这个:

var textcontrol = new sap.m.Text();
var textcontrol.setText("Hello World"); // Sets the text property in typescript.
var text = textControl.getText(); // Gets the text in javascript.

当我试图在我的声明文件中声明该方法时,我收到错误提示,说明不允许在外部环境中声明 setter 或 getter。因此,我猜这并不像我希望的那样工作(或者可能可以,只是我没有正确操作)。

在普通的 TypeScript 文件中,我可以使用 getter 和 setter

get Text(): string { return _text; };
set Text(value: string { _text = value };

但是在 d.ts 文件中我不能。

是否有可能在 d.ts 文件中声明该行为?

我能想到两个选择:

  1. 以某种方式将我的定义做成一个内部模块,并封装所有类以匹配 JS 的语法
  2. 不生成 d.ts 文件,而是生成普通的 ts 文件,这些文件实现虚拟返回值,并且只会编译成所需的代码。

将非常感激您的帮助。

编辑:一个具体的例子:

例如,我有这个 JavaScript “类” 来进行类型定义:

function Text() {}

Text.prototype.getText = function () {
    return this.Text;
}

Text.prototype.setText = function (value) {
    this.Text = value;
}

所以在 JavaScript 中的用法是:

var testtext = new Text();
testtext.setText("Hello World");
alert(testtext.getText())
// alerts Hello World

我想为此制作一个声明文件,并在 Typescript 中如下使用:

var testtext = new Text();
testtext.Text = "Hello World";
alert(testtext.Text);

毕竟这是可能的吗?

答案#1

如果你有一个带有 getter 和 setter 的属性,声明就像这样简单:

declare class Test {
    Text: string;
}

var x: Test;

x.Text = 'hello world';

类型定义中的语法与接口相同,所以 Text: string 就足够了。

期货

如果你只需要 getter 或 setter,这个功能即将到来——作为 TypeScript 2.0 中的 readonly 关键字

declare class Test {
    readonly Text: string;
}

...或者具有在接口中使用 get 和 set 关键字的能力。

declare class Test {
    get Text(): string;
}

方法

你也可以描述获取或设置后备属性的方法。它们与普通方法没有区别:

declare class Test {
    setText(v: string): void;
    getText(): string;
}

答案#2

TypeScript 贡献者的回答:

https://github.com/Microsoft/TypeScript/issues/10969#issuecomment-248192537

这是不可能的!

d.ts 文件中的 declare 不会生成任何代码,因此,你显然不能通过编写 declare 来替换任何东西。

唯一的方法是通过像这样声明属性来扩展 js 类:

var Text = ...<initializing code>...;

Object.defineProperty(Text.prototype, "Text", {
   get: function () { return this.getText(); },
   set: function (value) { this.setText(value); },
   enumerable: true,
   configurable: true
   });

(像我这样的新手:你不必在构造函数中这样做。)

在 get 和 set 函数中只需调用 getter 和 setter 方法即可。这不会影响 JS 代码(至少不会影响我的代码),因此,如果调用频繁,也会影响你转译后的 JS 性能。

谢谢你,索尼,感谢你的帮助。