Declare recursivley method chaining in TypeScript

Viewed 42

I have the following function that returns dynamic object in vanilla JS:

function myFunc(props) {
  return Object.keys(props).reduce((acc, key) => ({
    ...acc, [key](val) {
      console.log(val);
      return this;
    } 
  }), {});
}

And an object with that function above:

const myProps = {
  counter: 0,
  isCounting: false,
}

const obj = {
  myFunc: myFunc(myProps),
  anotherFunc: () => {},
  moreFunc: () => {},
}

And I want to decalre this object in my .d.ts file but I'm not sure what is the best way to define a type for recursive method chaining..

I tried using the following type:

type Obj<T> = {
  myFunc: () => Record<keyof T, () => this>;
  anotherFunc: () => void;
  moreFunc: () => void;
}

But the this keyword is referring to the type instance itself and not the myFunc object. Meaning I get also the anotherFunc and moreFunc in it instead of just the dynamic keys from myProps.

Can someone help with this implementation?

1 Answers

You can define this in a TypeScript interface:

interface Obj {
    [key: string]: (val: string) => this
}

const obj: Obj = {
  foo(val) {
    console.log('foo:', val);
    return this;
  },
  bar(val) {
    console.log('bar:', val);
    return this;
  }
}

I've assumed that the val arguments are string.

Edit: I've just seen your comment on your post - you can capture the key dynamically with [key: string]. I've updated my answer.

Related