I would like for typescript to recognize changes I make to the Object.prototype. Ideally, I would like to be able to do something like:
Object.prototype.l = function (title: string) => {
console.log({[title]: this})
return this
}
const bar = foo().l('bar')
The only downside is that typescript will show .l('bar')
as an error. For context, my scripts tend to usually look something like this:
export function updateTaxRecord(context: updateTaxRecordContext): boolean {
let successResponse = false
try {
console.log(context.type)
if (context.type != 'ui') return
console.log(context.fieldChanged)
if (context.fieldChanged != 'total') return
const locale = context.user.getNativeLocale()
console.log(locale)
const response = https.get(`./taxFormula/${locale}`)
console.log(response)
if (response.code[0] != '2') return
const formula = JSON.parse(response.body).taxRule
console.log(formula)
const tax = getTaxInfo(context, formula)
console.log(tax)
context.record.update('tax_info', tax)
successResponse = true
} catch (error) {
console.error(error)
} finally {
return successResponse
}
because there are many undocumented behaviors with the API that I am working with. I need typescript to keep track of the various idiosyncrasies which I record in a .d.ts file. However, the console.logs everywhere make for clunky code, and I find myself thinking, what if I could just do this:
function updateTaxRecord(context: updateTaxRecordContext): boolean {
let successResponse = false
try {
if (context.type.l('type') != 'ui') return
if (context.fieldChanged.l('fieldChanged') return
const locale = context.user.getNativeLocale().l('locale')
const response = https.get(`./taxFormula/${locale}`).l('response')
if (response.code[0] != '2') return
const formula = JSON.parse(response.body).taxRule.l('formula')
const tax = getTaxInfo(context, formula).l('tax')
context.record.update('tax_info', tax)
successResponse = true
} catch (error) {
console.error(error)
} finally {
return successResponse
}
which is significantly more precise. Plus, I could just forget about logging while I am writing the code and write a vim macro at the end to match the const
then yank the variable name and add the .l at the end.
What I have tried is
interface Object {
l(title: string): any
}
and in a .d.ts file
declare global {
interface Object {
l(title: string): any
}
}
These did not remove the error. I am looking to get it working and not a lecture on what good/clean code looks like. For context, I am writing server-side javascript/typescript that is not in Node.js and I have timed scripts and found no difference in how long the script runs when Object.prototype is modified. I am open to a JsDoc solution if that is what it takes. I saw that there were slightly similar questions asked here, but they did not actually solve the issue.
You should extend Object interface by d.ts file:
// global.d.ts
interface Object {
l<T>(this: T, title: string): T
}
and properly define type for l
function in the code:
// some.js
/**
* @template T
* @this {T}
* @param {string} title
* @returns {T}
*/
Object.prototype.l = function(title) {
console.log({ [title]: this })
return this
};
({name: "foo"}).l("name").name;
Function.l("bind").bind;