繁体   English   中英

在 typescript class 上定义属性而不定义类型的方法

[英]Way to define properties on typescript class without defining type

我在Time下面有一个 class 。 我很好奇是否有一种方法可以定义语法上不同的 3 个属性,最好以一种我不必定义上述属性的方式。

export class Time {
  parsed: ParsedTime
  string: string
  minutes: number
  constructor (public time: TimeConstructable) {
    this.parsed = parseResolve(this.time); 
    this.string = toString(this.parsed)
    this.minutes = inMinutes(this.parsed);
  }
}

我已经尝试过了,但它不起作用,因为它们在初始化之前运行并且无权访问this.time

export class Time {
  constructor (public time: TimeConstructable) {}

  parsed = parseResolve(this.time); 
  string = toString(this.parsed)
  minutes = inMinutes(this.parsed);
}

Getter 很好,语法简洁,但每次检索属性时都会计算值,而不是像第一个示例中那样缓存:

export class Time {
  constructor (public time: TimeConstructable) {}

  get parsed () {
    return parseResolve(this.time); 
  }
  
  get string () {
    return toString(this.parsed)
  }

  get minutes () {
    return inMinutes(this.parsed);
  }
}

这有点不正统,但它是一种有趣的语法,缺点是它允许复杂且无意的构造函数类型。

export class Time {
  constructor (
    public time: TimeConstructable,
    public parsed = parseResolve(time),
    public string = toString(parsed),
    public minutes = inMinutes(parsed)
  ) {}
}

还有其他人吗?

class 在这里没有为您做任何有用的事情,因为它没有任何方法。 类很好地将实例数据对该数据进行操作的方法联系在一起——但如果其中一个缺失,则使用普通的 function 或普通的 object 更有意义。

这可能不适合您的实际用例,但鉴于问题中的代码,您可能会使用以下内容:

export const makeTime = (time: TimeConstructable) => ({
  parsed: parseResolve(time),
  string: toString(parsed),
  minutes: inMinutes(parsed),
});

然后根本不需要类型注释。

(就个人而言,我更喜欢避免使用类的原因之一是因为函数更易于键入 - TypeScript 的自动推理可以为您完成几乎所有的类型工作,让您只专注于程序的逻辑)

不幸的是,class 语法需要明确的成员声明。

话虽这么说,正如您所知道的,有一个方便的 TypeScript 简写,可让您直接将它们声明为构造函数 arguments,因为以这种方式分配它们很常见。 使用这种方法,我们只能编写一次。

但该速记仅适用于直接分配。 如果您尝试将其与转换结合使用,则需要不常见的逻辑,这会导致您指出的漏洞。

常见的解决方案确实是像在第一个示例中那样编写它:显式成员声明、转换方法以及在构造函数主体中分配转换后的值。 这使您至少可以编写两次成员名称,或者如果您有单独的转换方法(如果您稍后需要更新值很有用),甚至更多。

另一个解决方案确实利用了吸气剂。

每次检索属性时都会计算 Getters [...] 值,而不是像第一个示例中那样缓存

一个经典的解决方法是结合私有缓存实现惰性计算(正如您所做的那样)。 例如:

class Time {
  private _parsed: ParsedTime;

  get parsed() {
    // if not cached yet, lazy evaluate
    // (I assume null and undefined are not expected results)
    this._parsed ??= parseResolve(this.time);
    return this._parsed;
  }
}

IIRC,应该有一些库为这个用例提供装饰器,因为它也很常见。 但是自己写也不是很复杂。 使用这样的装饰器,您可能需要更少的写作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM