Reputation: 882
I am familiar with the Kotlin extension function let
(and related) (cf. https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html).
I wanted to use something similar in TypeScript, using augmentation (or is it called declaration merging?). So I thought I can add the let
method to the Object
superclass.
How can I do it? I thought of something like the following, but that didn't work. Typescript doesn't seem to augment, but to solely use the following interface.
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)
}
EDIT:
Test cases would be:
'42'.let(it => alert(it))
'foo'.let(it => it.toUpperCase())
(i. e. let
would be available on any objects, in this case strings)
Upvotes: 2
Views: 2518
Reputation: 2663
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
EDIT 1
Updated the above to reflect better typing of the this
argument + examples
EDIT 2
let
on the Object
interface merges that declaration with the rest of the Object
interface. See Declaration mergingimport
and/or export
) you do the declaration in a global scope:
declare global {
interface Object {
...
}
}
See Global augmentationthis
argument in the method declaration declares the type of this
in the method signature. See Polymorphic this
typesmethod<T>(this: T)
, we make TypeScript know that the this
argument should take the form of the type the method is executed on. That way, if the method exists on a type (and it does, since we augmented the Object
interface), using it on that type causes the this
argument to be of that type.Upvotes: 2