Comments (13)
I would also like to useFlag
to be typeable. You could do something like:
export function useFlags<F extends LDFlagSet>(): F {
...
}
This way you can do:
export interface MyFlags {
addServicesRevenueDialog: boolean;
}
...
export const MyComponent: React.FC<IProps> = (props) => {
const flags = useFlags<MyFlags>();
// TypeScript knowns about "addServicesRevenueDialog"
flags.addServicesRevenueDialog
return ...
}
I would also suggest updating LDFlagValue
to something like:
-export type LDFlagValue = any;
+export type LDFlagValue = boolean | number | string | undefined;
from js-sdk-common.
+1 on this issue. In particular the use of an index signature with a value of any
is difficult to correct for. Since TS interfaces don't let you subtract an index signature, you can't supply a more specific type in your own declaration file.
Something like this should work but it doesn't, as all other string keys still have an any
value on the interface:
declare module 'launchdarkly-js-sdk-common' {
export interface LDFlagSet {
testFlag: boolean,
}
}
I agree re making useFlags
hook generic. It's fine if the type defaults to the flexible LDFlagSet
but that should not be hardcoded as the return value in LD module's useFlags.d.ts
.
from js-sdk-common.
Is there any update on this request?
from js-sdk-common.
Also looking for an update on this request! Thanks!
from js-sdk-common.
So the above works out of the box for us with typescript by defining the file above in the root project directory. An example in vscode:
You're right in that it doesn't fully protect, since the service and code can get out of sync, but it does greatly improve the out of the box experience. This keeps all of our feature flag definitions in a single file, so the manual effort to keep things in sync is greatly decreased.
This doesn't prevent the following though (fake flag is typed as any
and doesn't create compiler errors):
As an alternative, what we ended up doing was this:
and then we enabled the eslint rules:
Which works decently well, but would still prefer a different method that happens within ts native instead of enforced by eslint rules
from js-sdk-common.
I can't imagine how this could possibly work. It might help if you could provide some kind of example of what you'd like your code to look likeβ I mean, not just how you would access the flag, but how you would "define an override somewhere in the code" to enforce this typing. I also can't tell if you're actually talking about typing as in the data type of the flag value (which can't really be enforced in code, since you can change the variation values to any type on the service side), or just the existence of a specific flag key (even though you can't prevent a flag from being deleted on the service side either).
from js-sdk-common.
I'm sorry, I'm having trouble following your example - it seems like the code sample you posted in the PR description doesn't match what you're saying in the most recent comment, so I'm not sure what you meant by "the above works out of the box for us with typescript by defining the file above". You've provided two different versions of launchdarkly-js-sdk-common.d.ts
, and no example of what's in FeatureFlagSet
.
from js-sdk-common.
Oh sorry, i missed a file, FeatureFlagSet is just:
export interface FeatureFlagSet {
"input-update-on-enter": boolean;
"multiplayer-test-page": boolean;
multiplayer: boolean;
"data-connections": boolean;
comments: boolean;
"cache-default-app-state": boolean;
"story-mode": boolean;
notifications: boolean;
runButtonInput: boolean;
"single-monaco": boolean;
"org-migration": boolean;
}
So restating my post in a more concise way:
We can get auto-completion for useFlags
by adding an additional type definition for launchdarkly-js-sdk-common.d.ts
in our src folder, and using declaration merging (https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces) on the interface. However, declaration merging is purely additive, and still allows any other feature flag to be returned from useFlags
with the type of any
. It would be ideal if there were a way this could be even more typesafe, where referring to a missing feature flag in useFlags
would return an undefined error instead.
As an alternative, we have just been using eslint rules to disallow using useFlags
directly, and instead created our own useHexFlags
that just casts useFlags
using our typed feature flag files.
from js-sdk-common.
Regarding the type definition of LDFlagValue
, please see #16.
from js-sdk-common.
+1 for the desire to make flags type-safe.
from js-sdk-common.
IMO a better solution here would be to add typesafe methods to LDClient
like the Java client such as boolVariation
, stringVariation
etc that only accept default values of the correct type and return values of the correct type (throwing an error if the resolved value is not of the correct type)
from js-sdk-common.
Raised a similar issue on the new repo launchdarkly/js-core#285
from js-sdk-common.
This is available for testing launchdarkly/js-core#285 (comment)
from js-sdk-common.
Related Issues (20)
- LDFlagValue TypeScript type should be `unknown` HOT 9
- When bootstrapping a non valid object, it still resolves immediately HOT 5
- The track method is inconsistent with the TypeScript typings.d.ts file HOT 3
- Store hash value not updated by ldClient.identify() HOT 4
- uuid package needs upgrade to version 7+ HOT 5
- SyntaxError: Unexpected token H in JSON at position 4104 HOT 6
- Library does not catch errors when changing localstorage HOT 7
- Mistake in type docs about omit user key HOT 5
- JSON.Parse unhandled errors happening for a small % of our clients HOT 1
- Re-bootstrap on identify HOT 10
- TypeErrors in diagnosticEvents HOT 5
- Expose a hook to surface when fresh flags have been fetched HOT 5
- consider correcting typing of `LDOptions`'s `bootstrap` HOT 7
- Network requests to fetch flags are not retried unless the client successfully retrieves flags from localStorage HOT 1
- Node circular dependency warning on 4.x branch HOT 2
- Adding missing type definitions "inExperiment" HOT 1
- LDContext type is incorrect and errors when accessing `kind` property HOT 4
- Use `unknown` instead of `any` HOT 1
- `events.slice` is not a function HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from js-sdk-common.