Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve useDataProvider types #6627

Merged
merged 1 commit into from
Sep 29, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions packages/ra-core/src/dataProvider/useDataProvider.ts
Original file line number Diff line number Diff line change
@@ -104,8 +104,11 @@ import {
* // - FETCH_END
*/
const useDataProvider = <
TDataProvider extends DataProvider = DataProvider
>(): DataProviderProxy<TDataProvider> => {
TDataProvider extends DataProvider = DataProvider,
TDataProviderProxy extends DataProviderProxy<
TDataProvider
> = DataProviderProxy<TDataProvider>
>(): TDataProviderProxy => {
const dispatch = useDispatch() as Dispatch;
const dataProvider = ((useContext(DataProviderContext) ||
defaultDataProvider) as unknown) as TDataProvider;
@@ -117,7 +120,7 @@ const useDataProvider = <
const store = useStore<ReduxState>();
const logoutIfAccessDenied = useLogoutIfAccessDenied();

const dataProviderProxy = useMemo<DataProviderProxy<TDataProvider>>(() => {
const dataProviderProxy = useMemo(() => {
return new Proxy(dataProvider, {
get: (target, name) => {
if (typeof name === 'symbol') {
@@ -217,7 +220,7 @@ const useDataProvider = <
});
}, [dataProvider, dispatch, isOptimistic, logoutIfAccessDenied, store]);

return dataProviderProxy;
return (dataProviderProxy as unknown) as TDataProviderProxy;
};

// get a Promise that resolves after a delay in milliseconds
48 changes: 44 additions & 4 deletions packages/ra-core/src/types.ts
Original file line number Diff line number Diff line change
@@ -229,15 +229,15 @@ export type DataProviderResult<RecordType = Record> =
// This generic function type extracts the parameters of the function passed as its DataProviderMethod generic parameter.
// It returns another function with the same parameters plus an optional options parameter used by the useDataProvider hook to specify side effects.
// The returned function has the same result type as the original
type DataProviderProxyMethod<DataProviderMethod> = DataProviderMethod extends (
...a: any[]
) => infer Result
type DataProviderProxyMethod<
TDataProviderMethod
> = TDataProviderMethod extends (...a: any[]) => infer Result
? (
// This strange spread usage is required for two reasons
// 1. It keeps the named parameters of the original function
// 2. It allows to add an optional options parameter as the LAST parameter
...a: [
...Args: Parameters<DataProviderMethod>,
...Args: Parameters<TDataProviderMethod>,
options?: UseDataProviderOptions
]
) => Result
@@ -249,6 +249,46 @@ export type DataProviderProxy<
[MethodKey in keyof TDataProvider]: DataProviderProxyMethod<
TDataProvider[MethodKey]
>;
} & {
getList: <RecordType extends Record = Record>(
resource: string,
params: GetListParams,
options?: UseDataProviderOptions
) => Promise<GetListResult<RecordType>>;

getOne: <RecordType extends Record = Record>(
resource: string,
params: GetOneParams,
options?: UseDataProviderOptions
) => Promise<GetOneResult<RecordType>>;

getMany: <RecordType extends Record = Record>(
resource: string,
params: GetManyParams,
options?: UseDataProviderOptions
) => Promise<GetManyResult<RecordType>>;

getManyReference: <RecordType extends Record = Record>(
resource: string,
params: GetManyReferenceParams,
options?: UseDataProviderOptions
) => Promise<GetManyReferenceResult<RecordType>>;

update: <RecordType extends Record = Record>(
resource: string,
params: UpdateParams,
options?: UseDataProviderOptions
) => Promise<UpdateResult<RecordType>>;

create: <RecordType extends Record = Record>(
resource: string,
params: CreateParams
) => Promise<CreateResult<RecordType>>;

delete: <RecordType extends Record = Record>(
resource: string,
params: DeleteParams
) => Promise<DeleteResult<RecordType>>;
};

export type MutationMode = 'pessimistic' | 'optimistic' | 'undoable';