Skip to content

Commit 3299aad

Browse files
authored
Merge pull request #311 from Flagsmith/fix/use-flags-typing
fix: added-key-of-generic-record-and-tests
2 parents ad239e5 + 0b58c77 commit 3299aad

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

react.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export declare const FlagsmithProvider: FC<FlagsmithContextType>;
2626
export declare function useFlags<
2727
F extends string | Record<string, any>,
2828
T extends string = string
29-
>(_flags: readonly F[], _traits?: readonly T[]): UseFlagsReturn<F, T>;
29+
>(_flags: readonly (F | keyof F)[], _traits?: readonly T[]): UseFlagsReturn<F, T>;
3030
export declare const useFlagsmith: <F extends string | Record<string, any>,
3131
T extends string = string>() => IFlagsmith<F, T>;
3232
export declare const useFlagsmithLoading: () => LoadingState | undefined;

react.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export function useFlags<
158158
F extends string | Record<string, any>,
159159
T extends string = string
160160
>(
161-
_flags: readonly F[], _traits: readonly T[] = []
161+
_flags: readonly (F | keyof F)[], _traits: readonly T[] = []
162162
){
163163
const firstRender = useRef(true)
164164
const flags = useConstant<string[]>(flagsAsArray(_flags))

test/react-types.test.tsx

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import {render} from '@testing-library/react';
33
import {FlagsmithProvider, useFlags, useFlagsmith} from '../lib/flagsmith/react';
44
import {getFlagsmith,} from './test-constants';
5+
import { IFlagsmithTrait } from '../types';
56

67

78
describe.only('FlagsmithProvider', () => {
@@ -51,13 +52,16 @@ describe.only('FlagsmithProvider', () => {
5152
});
5253
it('should allow supplying interface generics to useFlags', () => {
5354
const FlagsmithPage = ()=> {
54-
const typedFlagsmith = useFlags<
55-
{
56-
stringFlag: string
57-
numberFlag: number
58-
objectFlag: { first_name: string }
59-
}
60-
>([])
55+
interface MyFeatureInterface {
56+
stringFlag: string
57+
numberFlag: number
58+
objectFlag: { first_name: string }
59+
}
60+
const typedFlagsmith = useFlags<MyFeatureInterface>(["stringFlag", "numberFlag", "objectFlag"])
61+
62+
// @ts-expect-error - feature not defined
63+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
64+
const wrongTypedFlagsmith = useFlags<MyFeatureInterface>(["non-existing-flag"])
6165
//@ts-expect-error - feature not defined
6266
typedFlagsmith.fail?.enabled
6367
//@ts-expect-error - feature not defined
@@ -72,11 +76,11 @@ describe.only('FlagsmithProvider', () => {
7276
//eslint-disable-next-line @typescript-eslint/no-unused-vars
7377
const numberFlag: number = typedFlagsmith.numberFlag?.value
7478
//eslint-disable-next-line @typescript-eslint/no-unused-vars
75-
const firstName: string = typedFlagsmith.objectFlag?.value.first_name
79+
const firstName: string = typedFlagsmith.objectFlag?.value?.first_name
7680

7781
// @ts-expect-error - invalid does not exist on type announcement
7882
//eslint-disable-next-line @typescript-eslint/no-unused-vars
79-
const invalidPointer: string = typedFlagsmith.objectFlag?.value.invalid
83+
const invalidPointer: string = typedFlagsmith.objectFlag?.value?.invalid
8084

8185
// @ts-expect-error - feature should be a number
8286
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -92,4 +96,30 @@ describe.only('FlagsmithProvider', () => {
9296
</FlagsmithProvider>
9397
);
9498
});
99+
it('should allow supplying string type to useFlags', () => {
100+
const FlagsmithPage = ()=> {
101+
type StringTypes = "stringFlag" | "numberFlag" | "objectFlag"
102+
const typedFlagsmith = useFlags<StringTypes>(["stringFlag", "numberFlag", "objectFlag"])
103+
104+
// @ts-expect-error - feature not defined
105+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
106+
const wrongTypedFlagsmith = useFlags<StringTypes>(["non-existing-flag"])
107+
108+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
109+
const stringFlag: IFlagsmithTrait = typedFlagsmith.stringFlag
110+
//eslint-disable-next-line @typescript-eslint/no-unused-vars
111+
const numberFlag: IFlagsmithTrait = typedFlagsmith.numberFlag
112+
//eslint-disable-next-line @typescript-eslint/no-unused-vars
113+
const firstName: IFlagsmithTrait = typedFlagsmith.objectFlag
114+
115+
return <></>
116+
}
117+
const onChange = jest.fn();
118+
const {flagsmith,initConfig, mockFetch} = getFlagsmith({onChange})
119+
render(
120+
<FlagsmithProvider flagsmith={flagsmith} options={initConfig}>
121+
<FlagsmithPage/>
122+
</FlagsmithProvider>
123+
);
124+
});
95125
});

0 commit comments

Comments
 (0)