【问题标题】:Angular2 & Typescript: How to add string extension method/prototypeAngular2 & Typescript:如何添加字符串扩展方法/原型
【发布时间】:2017-04-27 02:16:04
【问题描述】:

我想将扩展方法format() 添加到String。所以我的期望是我可以在我的项目中的任何地方使用String.format。 我遵循了topic 的指导方针,但这无济于事。我收到了这个错误:

谁能帮帮我?

提前致谢。

p.s:我想像在 angular 1.xx 中一样添加扩展方法


编辑

使用declare global不会出错。

declare global {
interface String {
    format(): string;
}}

String.prototype.format = function () :string {
var result = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) {
    var reg = new RegExp("\\{" + i + "\\}", "gm");
    result = result.replace(reg, arguments[i + 1]);
}
return result;}

我们如何使用String.format('&lt;img alt="{0}" title="{0}" src="{1}" /&gt;', name, id); 由于format不需要参数

【问题讨论】:

  • 无论你有什么都应该工作。 Playground link
  • 应该提到这是一种可怕的做法。扩展原型也不是一个好习惯,但 String.format 甚至不是原型方法——后者至少可以像 '...'.format() 一样使用它。在 TypeScript 中使用全局变量作为命名空间是没有意义的。使用模块。如果您在 A1 中执行此操作并切换到 A2 和 TS,那么看起来很有可能最终停止这样做。

标签: angular typescript extension-methods


【解决方案1】:

对我来说,以下是在使用 TypeScript 2.8.4 的 Angular 6 项目中工作的。

在 typings.d.ts 文件中添加:

interface String {
  format(...args: string[]): string;
}

注意:无需“声明全局”。

在名为 string.extensions.ts 的新文件中添加以下内容:

interface String {
  format(...args: string[]): string;
}

String.prototype.format = function (...args: string[]): string {
  var s = this;
  return s.replace(/{(\d+)}/g, function (match, number) {
    return (typeof args[number] != 'undefined') ? args[number] : match;
  });
};

要使用它,首先导入它:

import '../../string.extensions';

显然,您的导入语句应该指向正确的路径。 在类的构造函数或任何方法中:

console.log("Hello {0}".format("world"));

【讨论】:

  • 谢谢你,这对我帮助很大。如果有人需要它,您可以在 tsconfig.json 中添加一个快捷方式:"paths": { "@extensions/*": [ "./*.extensions.ts" ] } 并像这样使用它:import '@extensions/string';
  • 关于路径的好提示@Gus
  • 这应该是公认的答案。这适用于 Angular 6,declare global 不是处理事情的最佳方式,import 专门用于避免这种情况。
  • 我没有看到typings.d.ts,我应该创建它吗?在哪里 ?以及如何将其包含在解决方案中?
  • @Robouste 您可以在 src 文件夹中创建它。请参阅我关于使用它的帖子,即“要使用它,首先要导入它”...
【解决方案2】:

基于this playground,它工作得很好。

它可能对您不起作用,因为您可能正在使用模块(导入/导出),在这种情况下,您需要在 global augmentation 中执行此操作:

declare global {
    interface String {
        foo(): number;
    }
}

那么在原型中添加foo就不会报错了。


编辑

似乎您想要在String 上使用静态函数,所以您需要这样做:

declare global {
    interface StringConstructor {
        format(): string;
    }
}

String.format = function (...args: string[]) {
    ...
}

我还在签名中添加了...args: string[],它告诉编译器该函数需要任意数量的字符串作为参数。

【讨论】:

  • 感谢您的回复。使用declare global 不会出错。但是如何在 typescript 中声明一个可以传递任何多个参数的方法呢? declare global { interface String { format(): string; } } String.prototype.format = function() { var result = arguments[0]; for (var i = 0; i &lt; arguments.length - 1; i++) { var reg = new RegExp("\\{" + i + "\\}", "gm"); result = result.replace(reg, arguments[i + 1]); } return result; }我无法使用:String.prototype.format('&lt;img alt="{0}" title="{0}" src="{1}" /&gt;',name, id);
  • 1.不要将代码放在 cmets 中,而是编辑您的问题并将代码放在那里,然后简单地评论答案并写下问题已更新,2.检查我修改后的答案
  • 正如我在更新的答案中所写,您需要将 format 函数作为静态方法添加到 String 类 (StringConstructor),而不是原型中...跨度>
  • 您的解决方案是我的期望。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 2017-04-17
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
相关资源
最近更新 更多