feat: Allow users to create type-safe/strictly typed feature flags with useFlags#151
feat: Allow users to create type-safe/strictly typed feature flags with useFlags#151ewlsh wants to merge 2 commits intolaunchdarkly:mainfrom
Conversation
|
Hello @ewlsh, thank you for the contribution! We will discuss the change and give you a reply after that. |
src/useFlags.ts
Outdated
| * @return All the feature flags configured in your LaunchDarkly project | ||
| */ | ||
| const useFlags = <T extends LDFlagSet = LDFlagSet>(): T => { | ||
| function useFlags<T extends Record<string, any> = LDFlagSet>(): T { |
There was a problem hiding this comment.
Apologies for the slow response here but there are a couple of build errors.
Please update any to LDFlagValue. Typescript complained about this. Also
| function useFlags<T extends Record<string, any> = LDFlagSet>(): T { | |
| function useFlags<T extends Record<string, LDFlagValue> = LDFlagSet>(): T { |
There is also a prettier issue which should be easy to fix. I will make sure this gets expedited and merged after these are fixed. Thank you.
There was a problem hiding this comment.
We're still carrying this patch internally, so returning to this with the hopes of upstreaming it.
I've fixed the tslint and prettier issues.
bbf47f9 to
ccf40f4
Compare
|
@yusinto this is updated. |
To fix this releaser error when trying to release react sdk 3.3.0:
```bash
stdout >> Installing typedoc
stderr >> npm WARN EBADENGINE Unsupported engine {
stderr >> npm WARN EBADENGINE package: '@testing-library/dom@10.1.0',
stderr >> npm WARN EBADENGINE required: { node: '>=18' },
stderr >> npm WARN EBADENGINE current: { node: 'v16.20.2', npm: '8.19.4' }
stderr >> npm WARN EBADENGINE }
stderr >> npm WARN EBADENGINE Unsupported engine {
stderr >> npm WARN EBADENGINE package: '@testing-library/react@15.0.7',
stderr >> npm WARN EBADENGINE required: { node: '>=18' },
stderr >> npm WARN EBADENGINE current: { node: 'v16.20.2', npm: '8.19.4' }
stderr >> npm WARN EBADENGINE }
```
Convert to function to allow overrides Closes launchdarkly#139
ccf40f4 to
56f5c66
Compare
|
Hello, Sorry I am late to looking at this, but I need some help understanding the goals better. My initial impression is that something like: Provides a non-generic hook and doesn't involve modifying the declaration of the underlying package. Conceptually though I am good with changing to a function, I think it generally should be a function. But I am not comfortable with the typing change. As modifying the declarations of the library resulting in different types shouldn't maintain an expectation of continued functionality or compatibility. The flags are always an LDFlagSet, which is intended to represent a object indexed by a string with values of type LDValue. If the strings are camel cased or kebab doesn't change that interface, but a customer can of course restrict it further to be a constrained set of strings (via their own hook). Thank you, |
@kinyoklion My understanding is that Right now the hook's typing is Would be closer to what you are suggesting, a And it allows... Lastly In my mind at least |
Requirements
Related issues
#139, launchdarkly/js-sdk-common#32
Describe the solution you've provided
This MR updates
useFlagsgenerics and definition to allow implementing codebases to specify their own strictly typed feature flag interface.By declaring
useFlagsasconstand not afunctionit is not possible to overload its definition. Function overloads allow implementing codebases to re-declareuseFlagsto be more strict.Additionally, currently the generic on
useFlagsis set toextends LDFlagSet, but this is not necessarily true. WhenuseCamelCaseFlagKeysistrue, the return value fromuseFlagscan differ fromLDFlagSetifLDFlagSethas been augmented for the client.Describe alternatives you've considered
I also considered introducing a second interface,
ReactLDFlagSet(or similar), which did not include an index type but this would not be backwards compatible and it seems like the goal is to have strict typing be opt-in.Open to other alternatives, in our codebase we've considered writing a wrapping function.
Additional context
Example codebase implementation using these changes: