type-fest icon indicating copy to clipboard operation
type-fest copied to clipboard

Proposal: `AppendKeys` `PrependKeys`

Open pkuczynski opened this issue 3 years ago • 2 comments

Would allow to easily modify all the keys of an interface by appending or prepending the given string:

interface Operations {
  get: () => any
  update: () => any
}

type CustomOperations = AppendKeys<Operations, 'Something'>

would produce a type equivalent to:

interface CustomOperations {
  getSomething: Operations['get']
  updateSomething: Operations['update']
}

My use case is that I have a generator function, which produces an object of methods and I would like to re-export the same interface with some custom names:

const operations = (id: number): Operations => {
  get: () => { ... }
  update: () => { ... }
}

const ship = (id: number): Operations<'Ship>> => {
  const { get, update } = operations(id)
  
  return {
     getShip: get
     updateShip: update
  }
}

I am willing to create PR once this is accepted...

pkuczynski avatar May 01 '21 12:05 pkuczynski

I cannot say I ever needed this, and I kinda feel like there must be a better way of solving this. For example, I don't see why the method names should change. It's already a unique instance. ship.getShip() feels moot. ship.get() would be clear enough.

I'll leave this open for others to comment.

Also, this should be AppendToKeys, not AppendKeys.

sindresorhus avatar May 02 '21 11:05 sindresorhus

Yeah, didn't like the naming myself but could not figure something else...

As for the usage, in my case, I have a core useApi hook that exports generic get, create, etc. And then I have useX and useY hooks, which use the useApi hook, initialize it with some values, and re-export those methods as getX, getY etc, so I can use them independently on one page. I could of course export with [] instead of {}, so giving custom names on the spread would be easily possible, yet I wanted the flexibility to easier cherry pick from {}.

Regardless of my exact usage, the implementation of that type would be fairly easy:

type AppendToKeys<Name extends string, T> = { [key in keyof T as ${string & key}${Name}]: T[key] }

Its just a proposal, so if anybody finds it useful, I can fire up PR...

pkuczynski avatar May 02 '21 11:05 pkuczynski