This MR updates useFlags generics and definition to allow implementing codebases to specify their own strictly typed feature flag interface.
// Before
declare const useFlags: <T extends LDFlagSet = LDFlagSet>() => T;
// After
declare function useFlags<T extends Record<string, any> = LDFlagSet>(): T;
By declaring useFlags as const and not a function it is not possible to overload its definition. Function overloads allow implementing codebases to re-declare useFlags to be more strict.
Additionally, currently the generic on useFlags is set to extends LDFlagSet, but this is not necessarily true. When useCamelCaseFlagKeys is true, the return value from useFlags can differ from LDFlagSet if LDFlagSet has 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:
Requirements
Related issues
139, https://github.com/launchdarkly/js-sdk-common/issues/32
Describe the solution you've provided
This MR updates
useFlags
generics and definition to allow implementing codebases to specify their own strictly typed feature flag interface.By declaring
useFlags
asconst
and not afunction
it is not possible to overload its definition. Function overloads allow implementing codebases to re-declareuseFlags
to be more strict.Additionally, currently the generic on
useFlags
is set toextends LDFlagSet
, but this is not necessarily true. WhenuseCamelCaseFlagKeys
istrue
, the return value fromuseFlags
can differ fromLDFlagSet
ifLDFlagSet
has 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: