我正在使用一种新方法扩展String原型链,但是当我尝试使用它时,它会抛出一个错误:property 'padZero' does not exist on type 'string'.谁能为我解决这个问题?
代码如下.您还可以在Typescript Playground中看到相同的错误.
interface NumberConstructor {
padZero(length: number);
}
interface StringConstructor {
padZero(length: number): string;
}
String.padZero = (length: number) => {
var s = this;
while (s.length < length) {
s = '0' + s;
}
return s;
};
Number.padZero = function (length) {
return String(this).padZero(length);
}
Run Code Online (Sandbox Code Playgroud)
Gre*_*Ros 79
此答案适用于TypeScript 1.8+.这类问题有很多其他答案,但它们似乎都涵盖旧版本.
在TypeScript中扩展原型有两个部分.
声明新成员,以便它可以传递类型检查.您需要声明一个与要修改的构造函数/类同名的接口,并将其放在正确的声明的命名空间/模块下.这称为范围扩充.
以这种方式扩展模块只能在特殊的声明.d.ts文件*中完成.
//in a .d.ts file:
declare global {
interface String {
padZero(length : number) : string;
}
}
Run Code Online (Sandbox Code Playgroud)
外部模块中的类型具有包含引号的名称,例如"bluebird".
全球类型,如模块名称Array<T>和String是global,没有任何报价.但是,在许多版本的TypeScript中,您可以完全放弃模块声明并直接声明接口,具有以下内容:
declare interface String {
padZero(length : number) : string;
}
Run Code Online (Sandbox Code Playgroud)
在1.8之前的某些版本中也是这种情况,在2.0之后的某些版本中也是如此,例如最新版本2.5.
请注意,除了文件中的declare语句之外,您不能拥有任何内容.d.ts,否则它将无效.
这些声明被添加到包的环境范围中,因此它们将应用于所有TypeScript文件,即使您从不直接import或///<reference直接使用文件.但是,您仍然需要导入在第二部分中编写的实现,如果忘记执行此操作,则会遇到运行时错误.
*从技术上讲,你可以通过这个限制并将声明放在常规.ts文件中,但这会导致编译器出现一些挑剔的行为,并且不建议这样做.
第2部分实际上是实现成员并将其添加到它应该存在的对象中,就像在JavaScript中一样.
String.prototype.padZero = function (this : string, length: number) {
var s = this;
while (s.length < length) {
s = '0' + s;
}
return s;
};
Run Code Online (Sandbox Code Playgroud)
请注意以下几点:
String.prototype而不仅仅是String,它是String构造函数,而不是它的原型.function而不是箭头函数,因为a function将正确地this从调用它的位置接收参数.箭头函数将始终使用this与其声明的位置相同的内容.有一次我们不希望发生这种情况是在扩展原型时.this,所以编译器知道this我们期望的类型.此部分仅适用于TS 2.0+.this如果您正在编译1.8-,请删除注释.没有注释,this可以隐式输入any.在TypeScript中,declare构造将成员添加到环境范围,这意味着它们出现在所有文件中.为了确保第2部分的实现已连接,import文件就在应用程序的开头.
您导入文件如下:
import '/path/to/implementation/file';
Run Code Online (Sandbox Code Playgroud)
没有任何进口.您也可以从文件中导入某些内容,但不需要导入在原型上定义的函数.
jer*_*ass 20
这是一个工作示例,一个简单的Camel Case字符串修饰符.
在我的index.d.ts中为我的项目
interface String {
toCamelCase(): string;
}
Run Code Online (Sandbox Code Playgroud)
在我的根本.ts可访问的地方
String.prototype.toCamelCase = function(): string {
return this.replace(/(?:^\w|[A-Z]|-|\b\w)/g,
(ltr, idx) => idx === 0
? ltr.toLowerCase()
: ltr.toUpperCase()
).replace(/\s+|-/g, '');
};
Run Code Online (Sandbox Code Playgroud)
这就是我需要做的就是让它在打字稿中工作^2.0.10.
我喜欢它 str.toCamelCase()
更新
我意识到我也有这种需要,这就是我所拥有的
interface String {
leadingChars(chars: string|number, length: number): string;
}
String.prototype.leadingChars = function (chars: string|number, length: number): string {
return (chars.toString().repeat(length) + this).substr(-length);
};
Run Code Online (Sandbox Code Playgroud)
所以console.log('1214'.leadingChars('0', 10));得到我0000001214
Jac*_*ues 12
对我来说,以下使用TypeScript 2.8.4在Angular 6项目中工作.
在typings.d.ts文件中添加:
interface Number {
padZero(length: number);
}
interface String {
padZero(length: number);
}
Run Code Online (Sandbox Code Playgroud)
注意:无需'声明全局'.
在名为string.extensions.ts的新文件中添加以下内容:
interface Number {
padZero(length: number);
}
interface String {
padZero(length: number);
}
String.prototype.padZero = function (length: number) {
var s: string = String(this);
while (s.length < length) {
s = '0' + s;
}
return s;
}
Number.prototype.padZero = function (length: number) {
return String(this).padZero(length)
}
Run Code Online (Sandbox Code Playgroud)
要使用它,首先导入它:
import '../../string.extensions';
Run Code Online (Sandbox Code Playgroud)
显然你的import语句应该指向正确的路径.
在你的类的构造函数或任何方法中:
var num: number = 7;
var str: string = "7";
console.log("padded number: ", num.padZero(5));
console.log("padding string: ", str.padZero(5));
Run Code Online (Sandbox Code Playgroud)
Ste*_*gin 10
如果要扩充class而不是instance,请扩充构造函数:
declare global {
interface StringConstructor {
padZero(s: string, length: number): string;
}
}
String.padZero = (s: string, length: number) => {
while (s.length < length) {
s = '0' + s;
}
return s;
};
console.log(String.padZero('hi', 5))
export {}
Run Code Online (Sandbox Code Playgroud)
*需要,如果你在底部空的出口declare global中.ts,并没有出口任何东西。这将强制文件成为模块。*
如果要在instance(aka prototype)上使用该功能,
declare global {
interface String {
padZero(length: number): string;
}
}
String.prototype.padZero = function (length: number) {
let d = String(this)
while (d.length < length) {
d = '0' + d;
}
return d;
};
console.log('hi'.padZero(5))
export {}
Run Code Online (Sandbox Code Playgroud)
解决方案非常简单,但实现该解决方案却并非如此。忽略得票最高的答案;其中大部分是不需要的,也不再起作用了。
索引.d.ts
不需要!
字符串.ts
interface String {
toProperCase(): string;
bool(): boolean;
}
String.prototype.toProperCase = function (): string {
return this.toLowerCase().replace(/\b\w/g, (c: string) => c.toUpperCase())
}
String.prototype.bool = function (): boolean {
return this.toLowerCase() == 'true';
};
Run Code Online (Sandbox Code Playgroud)
使用它
import './lib/strings'
var a = 'hello'
var b = a.toProperCase()
Run Code Online (Sandbox Code Playgroud)
输出:
你好
| 归档时间: |
|
| 查看次数: |
33198 次 |
| 最近记录: |