typescripttype-safetyfunction-prototypes

Typesafely extending Object prototype in TS


const via = Symbol('via')

declare global {
  interface Object {
    [via]<R>(cont:(self:this)=>R):R
  }
}

const test = [1,2,3][via](x=>x) // test is inferred as Object, it should be inferred as number[]

Is there a way to type annotate this correctly?


Solution

  • Use a generic parameter in the interface that TypeScript correctly infers the type of the caller and applies it to the function argument and return type:

    const via = Symbol('via');
    
    declare global {
      interface Object {
        [via]<R, T = this>(this: T, cont: (self: T) => R): R;
      }
    }
    
    Object.prototype[via] = function<R, T = this>(this: T, cont: (self: T) => R): R {
      return cont(this);
    };
    
    const test = [1, 2, 3][via](x => x);