Skip to content

Instantly share code, notes, and snippets.

@karanlyons
Last active August 7, 2019 06:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karanlyons/f402198802e79d7efdae2937705b79c5 to your computer and use it in GitHub Desktop.
Save karanlyons/f402198802e79d7efdae2937705b79c5 to your computer and use it in GitHub Desktop.
Procrastinate till you evaluate.
export type StringReturningFunction = (...args: any[]) => string;
interface LazyString extends String {}
interface LazyStringConstructor {
new <F extends StringReturningFunction>(
func: F,
...args: Parameters<F>
): LazyString;
<F extends StringReturningFunction>(func: F, ...args: Parameters<F>): string;
}
export const LazyString = <LazyStringConstructor>(
function LazyString<F extends StringReturningFunction>(
this: LazyString | any,
func: F,
...args: Parameters<F>
) {
if (this instanceof LazyString) {
this.toString = func.bind(this, ...args);
} else {
return func.call(this, ...args);
}
}
);
export type LazyStringFunc<F extends StringReturningFunction> = (
...args: Parameters<F>
) => LazyString;
LazyString.prototype = Object.create(String.prototype);
for (const prop of Object.getOwnPropertyNames(String.prototype)) {
if (prop === "toString") {
continue;
} else if (typeof String.prototype[prop] === "function") {
LazyString.prototype[prop] = function(): void {
return String.prototype[prop].apply(this.toString(), arguments);
};
} else {
Object.defineProperty(LazyString.prototype, prop, {
get: function(): void {
return this.toString()[prop];
}
});
}
}
function gettext(str: string) { return str; }
const gettextLazy = function (...args) {
return new LazyString(gettext, ...args);
} as LazyStringFunc<typeof gettext>;
console.log(gettextLazy("Hello!"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment