首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TypeScript中的匿名/内联接口实现

TypeScript中的匿名/内联接口实现
EN

Stack Overflow用户
提问于 2015-09-17 19:07:41
回答 1查看 20.9K关注 0票数 39

我刚刚开始使用TypeScript,我试图理解为什么下面的内联对象定义不被认为是有效的。我有一个对象集合-它们的类型与我无关,但它们实现了接口,因此当我遍历它们时,我知道接口方法将出现在集合中的每个对象中。

当我试图创建一个具有实现所需方法所需的私有信息的对象时,遇到了一个“编译器”错误:

代码语言:javascript
运行
复制
interface Doable {
    do();
}

function doThatThing (doableThing: Doable) {
    doableThing.do();
}

doThatThing({
    private message: 'ahoy-hoy!', // compiler error here
    do: () => {
        alert(this.message);
    }
});

编译器错误消息是“'{ message: string, do: () => void; }' 类型的参数不能赋值给Doable类型。必须指定已知属性,并且' message‘不存在于Doable类型”中。请注意,如果我在函数调用之外定义对象,则会给出相同的消息。

代码语言:javascript
运行
复制
var thing: Doable;
thing = {
    private message: 'ahoy-hoy!', // error here
    do: () => {
        alert(this.message);
    }
};
doThatThing(thing);

如果我也添加了“意想不到的”方法,也会出现同样的错误:

代码语言:javascript
运行
复制
doThatThing({
    do: () => {
        alert("ahoy hoy");
    },
    doSecretly: () => { // compiler error here now
        alert("hi there");
    }
});

我查看了JavaScript,发现内联对象定义中的this的作用域是全局对象:

代码语言:javascript
运行
复制
var _this = this; // wait, no, why!?
function doThatThing(doableThing) {
    doableThing.do();
}
doThatThing({
    message: 'ahoy-hoy!',
    do: function () {
        alert(_this.message); // uses global 
    }
});

我尝试搜索有关TypeScript中接口的内联实现的信息,但找不到任何与此问题相关的内容。

我可以确认“修复”编译后的JS可以正常工作:

代码语言:javascript
运行
复制
function doThatThing(doableThing) {
    doableThing.do();
}

doThatThing({
    message: 'ahoy-hoy!',
    do: function () {
        alert(this.message);
    }
});

这对我来说很有意义,因为(据我所知)这是隐式调用对象构造函数,所以this的作用域应该是新的对象实例。

似乎唯一的解决方案是将每个实现声明为实现接口的类,但这感觉真的是倒退/笨重,因为我将只有每个类的一个实例。如果被调用函数的唯一约定是实现接口,那么为什么对象不能包含额外的成员呢?

很抱歉,这比我预期的...in摘要要长,我在问:

  1. 为什么在TypeScript中那个内联接口实现(“匿名类”,可以说是in Java)被认为是无效的?具体地说,编译器错误意味着什么,它能防止什么?
  2. 为什么在“已编译”的JavaScript?
  3. Assuming中生成的全局对象的作用域重新分配是我的错误(例如,为了防止某些不希望出现的情况,编译器错误是必需的),唯一的解决方案是像这样提前显式声明一个类吗?

代码语言:javascript
运行
复制
interface Doable {
    do() : void;
}

class DoableThingA implements Doable { // would prefer to avoid this ...
    private message: string = 'ahoy-hoy';
    do() {
        alert(this.message);
    }
}

class DoableThingB implements Doable { // ... as well as this, since there will be only one instance of each
    do() {
        document.getElementById("example").innerHTML = 'whatever';
    }
}

function doThatThing (doableThing: Doable) {
    doableThing.do();
}

var things: Array<Doable>;
things = new Array<Doable>();
things.push(new DoableThingA());
things.push(new DoableThingB());

for (var i = 0; i < things.length; i++) {
    doThatThing(things[i]);
}

附注。编译器错误只在我今天升级到TS 1.6时出现,尽管编译后的JS中的错误作用域错误在1.6和1.5中都出现了。

更新: François Cardinaux提供了一个指向 的链接,该链接建议使用类型断言,但这只会删除编译器错误,实际上会由于不正确的scope而导致逻辑错误

代码语言:javascript
运行
复制
interface Doable {
    do();
}

function doThatThing (doableThing: Doable) {
    doableThing.do();
}

doThatThing(<Doable>{ // assert that this object is a Doable
    private message: 'ahoy-hoy!', // no more compiler error here
    do: () => {
        alert(this.message);
    }
});

看看编译后的JS,这是不正确的:

代码语言:javascript
运行
复制
var _this = this; // very wrong, and now hidden
function doThatThing(doableThing) {
    doableThing.do();
}
doThatThing({
    message: 'ahoy-hoy!',
    do: function () {
        alert(_this.message); // s/b "this.message", which works in JS (try it)
    }
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-18 15:14:55

好了,我终于发现了问题2的问题--我在这里使用胖箭头=>来声明对象的方法:

代码语言:javascript
运行
复制
doThatThing(<Doable>{ 
    private message: 'ahoy-hoy!', 
    do: () => { // using fat arrow: global scope replaces new object's scope
        alert(this.message);
    }
});

...which将全局作用域“吸收”到方法中。这个问题是使用更长的语法修复的,如下所示:

代码语言:javascript
运行
复制
doThatThing(<Doable>{
    private message: 'ahoy-hoy!',
    do: function() { // using "regular" anonymous function syntax, "this" meaning is preserved
        alert(this.message);
    }
});

因此,总结一下:

函数在我的代码中是一个拼写错误,我应该使用“

  1. unanswered;
  2. There ()”而不是"=>";并且,将对象与接口一起使用可以消除编译器错误。
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32628864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档