[英][Typescript]: How to type a generic function to accept a more specific object as argument?
[英]return different generic type via function's optional argument in typescript
我想實現我自己的 usePromise,例如
// if with filterKey(e.g `K=list`), fileNodes's type should be `FileNode` (i.e. T[K])
const [fileNodes, isOk] = usePromise(
() => {
return Promise.resolve({list:[]}) as Promise<{ list: FileNode[] }>;
},
{ initValue: [] },
"list",
);
// if with no filterKey, data's type should be `{list: FileNode[]}` (i.e. T)
const [data, isOk] = usePromise(
() => {
return Promise.resolve({list:[]}) as Promise<{ list: FileNode[] }>;
},
{ initValue: {list:[]} }
);
我使用K extends keyof T
檢查filterKey
及其類型K
T[K]
T
這是實現usePromise
的代碼。 我發現K extends keyof T
總是導致 false 。
如何修復我的代碼?
export function usePromise<T, K>(
factory: () => Promise<T>,
options: Options<K extends keyof T ? T[K] : T> = {},
filterKey?: K,
): [K extends keyof T ? T[K] : T, boolean] {
type R = K extends keyof T ? T[K] : T;
const [state, setState] = useState<R>(
options.initValue!,
);
const isLoadingRef = useRef(false);
useEffect(() => {
factory().then((r) => {
if (filterKey) {
setState((r as any)[filterKey] as unknown as R);
} else {
setState(r as unknown as R);
}
}).catch((res) => {
if (options.onError) options.onError(res);
else throw res;
});
}, []);
return [state, isLoadingRef.current] as [R, boolean];
}
您當前的usePromise
實現將K
推斷為string | undefined
當您期待'list'
時string | undefined
。 您可以通過限制K
的類型來解決此問題:
export function usePromise<T, K extends keyof T | undefined>
這是操場上的最小復制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.