Skip to content

How to handle this when this is a function #22285

Closed
@dagda1

Description

@dagda1

I have created this playground that shows the problem.

The code looks like this:

export interface Extender<A extends { new (name: string): A }> {
  instance: (constructor: { new() }, methods?: {}) => void;
  for: (value: any) => A;
  symbol: Symbol;
}

export function extend<A extends { new(name: string) }>(
  Class: A
): A & Extender<A> {
  const name = Class.name;
  const Extended = <A & Extender<A>>Class;

  let symbol = Symbol(name);

  Extended.instance = function(constructor, methods) {
    constructor.prototype[symbol] = methods;
  };

  Extended.symbol = symbol;

  Extended.for = function _for(value: any): A {
    let i = value[symbol];

    return i;
  };  

  const properties = getOwnPropertyDescriptors(Class.prototype);

    Object.keys(properties)
    .filter(key => key != "constructor")
    .forEach(key => {
      Extended.prototype[key] = Extended.prototype[key].bind(Extended.for);
    });

  return Extended;
}

interface Interface<A> {
  doSomething: (left: A, right: A) => A;
}

const Implementation = extend(class Implementation<A> implements Interface<A> {
  doSomething(left: A, right: A) {
    let { doSomething } = this(left);

    return doSomething(left, right);
  }
});

const { doSomething } = Implementation.prototype;

Implementation.instance(Object, {
  doSomething(o1, o2) {
    let properties = Object.assign({}, propertiesOf(o1), propertiesOf(o2));
    return Object.create(getPrototypeOf(o1), properties);
  }
});

doSomething({o: 1}, {b: 2});

How do I handle this on line 44 of the playground

let { doSomething } = this(left);

the call to this will return the specific doSomething.

At the moment I get the error, this lacks a callable signature.

If I add the false this param like this:

doSomething(this: (a: A) => Implementation<A>, left: A, right: A) {

And if I then export the function

export {doSomething} = Implementation.prototype;

And I then try to use the function:

doSomething({o: 1}, {b: 2}); I get the error:

The 'this' context of type 'void' is not assignable to method's 'this' of type '(a: any) => Implementation'.

I realise this is quite contrived but is this too contrived for typescript?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs More InfoThe issue still hasn't been fully clarified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions