打字稿计算的吸气剂不起作用

Posted

技术标签:

【中文标题】打字稿计算的吸气剂不起作用【英文标题】:Typescript computed getter not working 【发布时间】:2017-04-23 06:55:30 【问题描述】:

这个计算属性 lastSeenString 曾经为我工作:

export class User 
    public lastSeen?: Date;
    private _lastSeenString?:string = "";
    get lastSeenString():string 
        return Time.timeSince(this.lastSeen);
    

但现在lastSeenString 返回""。永远不会调用 getter 中的 return 语句。怎么会? lastSeen 已填充。

客户:

it('Displays the user\'s "last seen"', () => 
    component.user.lastSeen = new Date();
    fixture.detectChanges();
    expect(component.user.lastSeenString).toBe("less than a minute ago");
    expect(page.lastSeen.innerText).toBe("last seen less than a minute ago");
);

我的打字稿编译为es5。为什么getter里面的代码不执行?

应该执行但没有执行的时间类:

export class Time 
    public static timeSince(date: Date) 
        let start = +new Date();
        let elapsed = +new Date() - start;
        var seconds = Math.floor((elapsed) / 1000);

        // var seconds = Math.floor((new Date() - +date) / 1000);

        //var seconds = Math.floor(((new Date().getTime()/1000) - +date))


        var interval = Math.floor(seconds / 31536000);

        if (interval > 1) 
            return interval + " years";
        
        interval = Math.floor(seconds / 2592000);
        if (interval > 1) 
            return interval + " months";
        
        interval = Math.floor(seconds / 86400);
        if (interval > 1) 
            return interval + " days";
        
        interval = Math.floor(seconds / 3600);
        if (interval > 1) 
            return interval + " hours";
        
        interval = Math.floor(seconds / 60);
        if (interval > 1) 
            return interval + " minutes";
        
        return "less than a minute ago";
    

User类的实际实现:

export var SERENA: User = 
   id: 1,
   lastSeenString: "",
    lastSeen: new Date("October 13, 2016 11:13:00"),
    badges: ["active User", "helper"],
    memberSince: new Date("October 13, 2014")

我看到实现有 lastSeenString = "",但我认为这会触发 getter 而不仅仅是返回 ""

更新:我很确定这一定与仅导出该 JSON 对象并将其称为 User 有关。我想我必须更新它。

【问题讨论】:

【参考方案1】:

getter 是在 User 的原型上定义的——即作为类本身的一部分。您需要使用该类(例如使用 new User())构建您的实例,以便 getter 工作。

目前你只是构建一个普通的 javascript 对象,然后告诉 TypeScript 它与真正的用户对象的形状相同。这通过了类型检查,因为它相同的形状 - 读取其上的任何字段都将返回与您期望从真实 User 对象中获得的相同类型的值 - 但这并不能告诉您有关这些字段的基本行为的任何信息。

【讨论】:

在这种情况下,不仅 getter 和 setter 消失了,公共方法(如果有的话)也消失了。另请查看处理一致问题的following answer。此外,最好不要在域实体中包含方法(以及 getter 和 setter)以避免此问题。 @GieSpaepen 虽然我明白您的意思,但如果您在域模型中只有属性(没有方法),那么这将被视为“数据类”,这是一种代码味道,仅推荐用于用于原型设计,因为它会导致大型项目中的紧密耦合。 @GieSpaepen 但是您发布的答案是一个很好的解决方案,我认为我将用于我的模拟数据:)【参考方案2】:

就我而言,我从网络获取对象数据为 JSON。然后像这样分配数据:

   let newUser = Object.assign(new User(), data)

我可以访问所有公共数据和函数,但不能访问该对象内部对象的函数、getter 和 setter。所以即使我可以打印出来,我也无法访问私人数据。

   class User 
      name: string
      state: UserState
    

   class UserState 
      private _stateInfo: string
      getter()......
    

这样我就可以访问name,并且可以打印出state的数据。但是不能访问state里面的函数。

解决这个问题的方法是在传递User对象的数据时初始化新的UserState对象。

【讨论】:

不清楚您是如何解决问题的。解决方案不是与您最初的方法相反吗? let newUser = new User(data),然后在构造函数中,你把你的Object.assign(this, data)

以上是关于打字稿计算的吸气剂不起作用的主要内容,如果未能解决你的问题,请参考以下文章

反应打字稿打字不起作用

打字稿实例不起作用

打字稿'可选'(可为空)'?语法不起作用(部分)

打字稿RefForwardingComponent不起作用

打字稿异步/等待不起作用

打字稿重载箭头功能不起作用