打字稿如何扩充对象class?
Typescript how to augment Object class?
我熟悉 Kotlin 扩展函数 let
(及相关)(参见 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html)。
我想在 TypeScript 中使用类似的东西,使用扩充(或者称为声明合并?)。所以我想我可以将 let
方法添加到 Object
超类。
我该怎么做?我想到了类似下面的东西,但这没有用。 Typescript好像没有扩充,只是单独使用下面的接口。
interface Object {
let<T, R>(block: (t: T) => R): R
}
(Object.prototype as any).let = function<T, R>(block: (t: T) => R) {
return block(this)
}
编辑:
测试用例为:
'42'.let(it => alert(it))
'foo'.let(it => it.toUpperCase())
(即 let
可用于任何对象,在本例中为字符串)
TL;DR
interface Object {
let<T, R>(this: T, block: (t: T) => R): R;
}
Object.prototype.let = function <T, R>(this: T, block: (t: T) => R): R {
return block(this);
};
'42'.let(it => alert(it)); // let -> Object.let<string, void>(this: string, block: (t: string) => void): void
(42).let(it => alert(it)); // let -> Object.let<number, void>(this: number, block: (t: number) => void): void
'foo'.let(it => it.toUpperCase()); // let -> Object.let<string, string>(this: string, block: (t: string) => string): string
['foo'].let(it => it[0].toUpperCase()); // let -> Object.let<string[], string>(this: string[], block: (t: string[]) => string): string
编辑 1
更新以上内容以反映 this
参数 + 示例的更好输入
编辑 2
说明
- 在
Object
接口上声明 let
将该声明与 Object
接口的其余部分合并。参见 Declaration merging
- 如果这个声明在一个模块中(一个包含
import
and/or export
的文件),你可以在全局范围内进行声明:
declare global {
interface Object {
...
}
}
参见 Global augmentation
- 在方法声明中使用
this
参数在方法签名中声明 this
的类型。参见 Polymorphic this
types
- TypeScript 需要一种隐式理解特定类型的方法,为此,我们将使用泛型。参见 Generics
- 将以上所有内容放在一起,通过声明
method<T>(this: T)
,我们让 TypeScript 知道 this
参数应该采用执行方法的类型的形式。这样,如果该方法存在于一个类型上(它确实存在,因为我们扩充了 Object
接口),在该类型上使用它会导致 this
参数属于该类型。
我熟悉 Kotlin 扩展函数 let
(及相关)(参见 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html)。
我想在 TypeScript 中使用类似的东西,使用扩充(或者称为声明合并?)。所以我想我可以将 let
方法添加到 Object
超类。
我该怎么做?我想到了类似下面的东西,但这没有用。 Typescript好像没有扩充,只是单独使用下面的接口。
interface Object {
let<T, R>(block: (t: T) => R): R
}
(Object.prototype as any).let = function<T, R>(block: (t: T) => R) {
return block(this)
}
编辑:
测试用例为:
'42'.let(it => alert(it))
'foo'.let(it => it.toUpperCase())
(即 let
可用于任何对象,在本例中为字符串)
TL;DR
interface Object {
let<T, R>(this: T, block: (t: T) => R): R;
}
Object.prototype.let = function <T, R>(this: T, block: (t: T) => R): R {
return block(this);
};
'42'.let(it => alert(it)); // let -> Object.let<string, void>(this: string, block: (t: string) => void): void
(42).let(it => alert(it)); // let -> Object.let<number, void>(this: number, block: (t: number) => void): void
'foo'.let(it => it.toUpperCase()); // let -> Object.let<string, string>(this: string, block: (t: string) => string): string
['foo'].let(it => it[0].toUpperCase()); // let -> Object.let<string[], string>(this: string[], block: (t: string[]) => string): string
编辑 1
更新以上内容以反映 this
参数 + 示例的更好输入
编辑 2
说明
- 在
Object
接口上声明let
将该声明与Object
接口的其余部分合并。参见 Declaration merging - 如果这个声明在一个模块中(一个包含
import
and/orexport
的文件),你可以在全局范围内进行声明:
参见 Global augmentationdeclare global { interface Object { ... } }
- 在方法声明中使用
this
参数在方法签名中声明this
的类型。参见 Polymorphicthis
types - TypeScript 需要一种隐式理解特定类型的方法,为此,我们将使用泛型。参见 Generics
- 将以上所有内容放在一起,通过声明
method<T>(this: T)
,我们让 TypeScript 知道this
参数应该采用执行方法的类型的形式。这样,如果该方法存在于一个类型上(它确实存在,因为我们扩充了Object
接口),在该类型上使用它会导致this
参数属于该类型。