Say you're writing some higher order functions that return other functions. In my case it was a utility that creates a typed hook to consume some context.
I wanted to let the consumer of this utility to have a reasonable name
property on the hook returned, not some generic library code name like "useContext"
.
The first attempt did not work.
const someFunc = () => { ... }
someFunc.name = someConfig.name
You get a nice error at least.
So then I think to myself π€ Do I know anything about dynamic naming in general in JavaScript?
π‘
Objects can have dynamic keys! With square brackets, we can stringify runtime values.
{ [someVar]: "woohoo" }
So, to solve my configurable function name problem, I used computed keys to create an object and computed keys again to destructure the function value.
π€― Right?
const custom = "Jerome"
const { [custom]: someFunc } = { [custom]: () => void 0 }
someFunc.name === "Jerome" // true
^ You can try that example in your browser console.
Pretty neat stuff! Here was my final solution, inspired by this cheatsheet.
import * as React from 'react';
export function assertContext<T>(
context: T | undefined,
config: {
hookName: string;
providerName: string;
},
): asserts context is T {
if (typeof context === 'undefined') {
throw new Error(`\`${config.hookName}\` must be used within \`<${config.providerName} />\``);
}
}
export function createUsableContext<T>(config: {
hookName: string;
providerName: string;
}): [() => T, React.Context<T | undefined>] {
const Context = React.createContext<T | undefined>(undefined);
// assign the function name dynamically by instantaneously assigning and destructuring an object field
// const useContext = ... would result in the fn name being `useContext`. Not helpful.
const { [config.hookName]: useContext } = {
[config.hookName]: (): T => {
const context = React.useContext(Context);
assertContext(context, config);
return context;
},
};
return [useContext, Context];
}
```
Top comments (1)
Very smart tricky! Perfect to decorate a method without lost its original name
Thanks for publish it β€οΈ