Skip to content

Commit

Permalink
improve types
Browse files Browse the repository at this point in the history
  • Loading branch information
tcastelly committed Aug 29, 2024
1 parent dca47cc commit 70fc60a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 51 deletions.
8 changes: 8 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ export type GetConfig<T> = $GetConfig<T> | Ref<$GetConfig<T>>

export type TypeAllowed = undefined | null | string | number | boolean | Obj

type Params<Z, A extends unknown[]> = (() => (Z | [...A])) |
ComputedRef<Z | [...A]> |
Ref<Z | [...A]> |
Z |
[...A]

export type RequiredParams<Z extends TypeAllowed, A extends TypeAllowed[]> = Params<Required<Z>, Required<A>>;

export type GetReturn<T> = {
isPending: ComputedRef<undefined | boolean>,
data: ComputedRef<T>,
Expand Down
42 changes: 19 additions & 23 deletions src/useAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,30 @@ import {
} from 'vue';
import { Result } from '@/useResult';
import uuid from '@/_base/uuid';
import type { TypeAllowed, UnwrappedPromiseType } from './index';
import type {
TypeAllowed,
UnwrappedPromiseType,
RequiredParams,
} from './index';

type OnErrorCb<T> = (e: null | Error, params: T) => unknown;

type OnStartCb<T> = (params: T) => unknown;

type OnEndCb<T, Z> = (res: T, params: Z) => unknown;

// params: ComputedRef<A> | Ref<A> | (() => A) | A = {} as A,

type Params<Z, A extends unknown[]> = (() => (Z | [...A])) |
ComputedRef<Z | [...A]> |
Ref<Z | [...A]> |
Z |
[...A]

const useAsync = <T, Z extends TypeAllowed, A extends TypeAllowed[]>(
func: ((...args: A) => Promise<T>) | ((args: Z) => Promise<T>),
params?: Params<Z, A>,
params?: RequiredParams<Z, A>,
enabled: Ref<boolean> | (() => boolean) = ref(true),
): {
isPending: Ref<undefined | boolean>,
data: ComputedRef<undefined | null | UnwrappedPromiseType<typeof func>>;
error: Ref<null | Error>,
reload: () => unknown,
onError: (cb: OnErrorCb<Params<Z, A>>) => unknown,
onStart: (cb: OnStartCb<Params<Z, A>>) => unknown,
onEnd: (cb: OnEndCb<UnwrappedPromiseType<typeof func>, Params<Z, A>>) => unknown,
onError: (cb: OnErrorCb<RequiredParams<Z, A>>) => unknown,
onStart: (cb: OnStartCb<RequiredParams<Z, A>>) => unknown,
onEnd: (cb: OnEndCb<UnwrappedPromiseType<typeof func>, RequiredParams<Z, A>>) => unknown,
promise: ComputedRef<null | ReturnType<typeof func>>,
} => {
const isPending = ref<undefined | boolean>();
Expand All @@ -43,20 +39,20 @@ const useAsync = <T, Z extends TypeAllowed, A extends TypeAllowed[]>(

const error: Ref<null | Error> = ref(null);

const onErrorList: Array<OnErrorCb<Params<Z, A>>> = [];
const onErrorList: Array<OnErrorCb<RequiredParams<Z, A>>> = [];

const onStartList: Array<OnStartCb<Params<Z, A>>> = [];
const onStartList: Array<OnStartCb<RequiredParams<Z, A>>> = [];

const onEndList: Array<OnEndCb<T, Params<Z, A>>> = [];
const onEndList: Array<OnEndCb<T, RequiredParams<Z, A>>> = [];

// for legacy use case
const d = ref<null | Promise<T>>(null);

const wrapParams = computed(() => {
if (typeof params === 'function') {
return params();
return params() as RequiredParams<Z, A>;
}
return unref(params);
return unref(params) as RequiredParams<Z, A>;
});

const lastUnwrapParams = ref();
Expand All @@ -69,7 +65,7 @@ const useAsync = <T, Z extends TypeAllowed, A extends TypeAllowed[]>(
});

// generate new xhr/promise
const _reload = (_params: Z | [...A]) => {
const _reload = (_params: RequiredParams<Z, A>) => {
if (!_enabled.value) {
return null;
}
Expand All @@ -80,7 +76,7 @@ const useAsync = <T, Z extends TypeAllowed, A extends TypeAllowed[]>(
error.value = null;

// possible to call with rest params
const funcDefault = func as ((args: Z) => Promise<T>);
const funcDefault = func as ((args: RequiredParams<Z, A>) => Promise<T>);

// call with only one param
const funcRest = func as ((...args: A) => Promise<T>);
Expand Down Expand Up @@ -113,15 +109,15 @@ const useAsync = <T, Z extends TypeAllowed, A extends TypeAllowed[]>(

const reload = () => _reload(wrapParams.value);

const onError = (cb: OnErrorCb<Params<Z, A>>) => {
const onError = (cb: OnErrorCb<RequiredParams<Z, A>>) => {
onErrorList.push(cb);
};

const onStart = (cb: OnStartCb<Params<Z, A>>) => {
const onStart = (cb: OnStartCb<RequiredParams<Z, A>>) => {
onStartList.push(cb);
};

const onEnd = (cb: OnEndCb<UnwrappedPromiseType<typeof func>, Params<Z, A>>) => {
const onEnd = (cb: OnEndCb<UnwrappedPromiseType<typeof func>, RequiredParams<Z, A>>) => {
onEndList.push(cb);
};

Expand Down
59 changes: 31 additions & 28 deletions src/useXhr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
GetConfig,
GetReturn,
Obj,
RequiredParams,
TypeAllowed,
XhrConfig,
XhrGet,
Expand All @@ -39,20 +40,15 @@ type $$GetConfigArg<T> = Omit<$GetConfigArgs<T>, 'url'> & {
url?: string,
}

type Params<Z> = (() => Z) |
ComputedRef<Z> |
Ref<Z> |
Z

// used as default `onError`
const _blank = () => {
};

declare type UseXhr<T, Z extends TypeAllowed> = Partial<{
declare type UseXhr<T, Z extends TypeAllowed, A extends TypeAllowed[]> = Partial<{
// global callback for VueJS 2 plugin compatibility
onError: OnErrorCb<T>,
onStart: OnStartCb<T, Params<Z>>,
onEnd: OnEndCb<T, Params<Z>>,
onStart: OnStartCb<T, RequiredParams<Z, A>>,
onEnd: OnEndCb<T, RequiredParams<Z, A>>,
onProgress: (e: ProgressEvent) => any,
onAbort: (e: ProgressEvent) => any,
//
Expand All @@ -63,7 +59,7 @@ declare type UseXhr<T, Z extends TypeAllowed> = Partial<{

const getTokenValue = (token: undefined | Token): undefined | null | string => unref<undefined | string | null>(token);

export default function <T, Z extends TypeAllowed>(args?: UseXhr<T, Z>) {
export default function <T, Z extends TypeAllowed, A extends TypeAllowed[]>(args?: UseXhr<T, Z, A>) {
const {
onError,
onStart,
Expand All @@ -90,9 +86,9 @@ export default function <T, Z extends TypeAllowed>(args?: UseXhr<T, Z>) {
/**
* For GET it's possible to add cache
*/
function get<TT = T, ZZ = Z>(
function get<TT = T, ZZ extends TypeAllowed = Z, AA extends TypeAllowed[] = A>(
parametersObj: GetConfig<ZZ>,
params?: Params<ZZ>,
params?: RequiredParams<ZZ, AA>,
enabled?: Enabled,
): GetReturn<TT> {
const xhr: Xhr<TT> = new Xhr<TT>();
Expand Down Expand Up @@ -130,7 +126,7 @@ export default function <T, Z extends TypeAllowed>(args?: UseXhr<T, Z>) {

// use params from second args of get function
if (!params) {
params = (unwrapParametersObj.params || {}) as Params<ZZ>;
params = (unwrapParametersObj.params || {}) as RequiredParams<ZZ, AA>;
}

duration = unwrapParametersObj.cacheDuration;
Expand All @@ -152,15 +148,15 @@ export default function <T, Z extends TypeAllowed>(args?: UseXhr<T, Z>) {
}

// merge params
let p = unref(_getParams.params || params || {} as Params<ZZ>);
let p = unref(_getParams.params || params || {});
if (typeof p === 'function') {
p = (p as () => ZZ)();
p = (p as () => ZZ)() as RequiredParams<ZZ, AA>;
}

_getParams.params = {
...p as ZZ,
_getParams.params = ({
...p,
...(isRef(params) ? (params.value || {}) : params),
};
}) as ZZ;

url = typeof _url === 'function' ? _url(_getParams.params) : unref(_url);
_getParams.url = url;
Expand Down Expand Up @@ -285,28 +281,26 @@ export default function <T, Z extends TypeAllowed>(args?: UseXhr<T, Z>) {
};
}

const update = <TT = T, ZZ = Z>(method: 'post' | 'delete' | 'put', xhrConfig?: $UpdateConfigArgs, params?: Params<ZZ>) => {
const update = <TT = T, ZZ extends TypeAllowed = Z, AA extends TypeAllowed[] = A>(
method: 'post' | 'delete' | 'put',
xhrConfig?: $UpdateConfigArgs,
params?: RequiredParams<ZZ, AA>,
) => {
const updateArgs = computed(() => {
const _postArgs: $UpdateConfigArgs<ZZ> = {};

const unwrapParametersObj = unref(xhrConfig || {} as XhrConfig);

// use params from second args of post function
if (!params) {
params = (unwrapParametersObj.params || {}) as Params<ZZ>;
params = (unwrapParametersObj.params || {}) as RequiredParams<ZZ, AA>;
}
_postArgs.params = unref<ZZ>(params as ZZ);

if (token) {
_postArgs.token = getTokenValue(token);
}

// merge params
let p = unref(_postArgs.params || params || {} as Params<ZZ>);
if (typeof p === 'function') {
p = (p as () => ZZ)();
}

_postArgs.url = unref(unwrapParametersObj.url);

return _postArgs;
Expand Down Expand Up @@ -344,11 +338,20 @@ export default function <T, Z extends TypeAllowed>(args?: UseXhr<T, Z>) {
};
};

const post = <TT = T, ZZ = Z>(xhrConfig?: $UpdateConfigArgs, params?: Params<ZZ>) => update<TT, ZZ>('post', xhrConfig, params);
const post = <TT = T, ZZ extends TypeAllowed = Z, AA extends TypeAllowed[] = A>(
xhrConfig?: $UpdateConfigArgs,
params?: RequiredParams<ZZ, AA>,
) => update<TT, ZZ, AA>('post', xhrConfig, params);

const put = <TT = T, ZZ = Z>(xhrConfig?: $UpdateConfigArgs, params?: Params<ZZ>) => update<TT, ZZ>('put', xhrConfig, params);
const put = <TT = T, ZZ extends TypeAllowed = Z, AA extends TypeAllowed[] = A>(
xhrConfig?: $UpdateConfigArgs,
params?: RequiredParams<ZZ, AA>,
) => update<TT, ZZ, AA>('put', xhrConfig, params);

const _delete = <TT = T, ZZ = Z>(xhrConfig?: $UpdateConfigArgs, params?: Params<ZZ>) => update<TT, ZZ>('delete', xhrConfig, params);
const _delete = <TT = T, ZZ extends TypeAllowed = Z, AA extends TypeAllowed[] = A>(
xhrConfig?: $UpdateConfigArgs,
params?: RequiredParams<ZZ, AA>,
) => update<TT, ZZ, AA>('delete', xhrConfig, params);

if (!legacy) {
onBeforeUnmount(() => {
Expand Down

0 comments on commit 70fc60a

Please sign in to comment.