As I delve into developing a custom useFetch composable for a Vue application, the focus seems to shift towards TypeScript. Essentially, my query revolves around conditionally asserting a type to a variable within a function, contingent on the type of an argument supplied to said function.
My understanding of both TypeScript and Vue is still in its nascent stage, leaving me unsure of the feasibility of my request. Should it prove to be unattainable, I am open to any guidance on restructuring the approach.
The crux of the matter lies in having fetchedData
assigned as either Ref<T>
when a defaultValue
(of type T) is provided, or Ref<T | undefined>
when no defaultValue
is specified. Below is the provided code snippet:
Corresponding snippet of the useFetch composable:
import type { Ref } from "vue";
import { ref } from "vue";
export default function useFetch<T>({
defaultValue,
}: {
defaultValue?: T;
} = {}) {
// The use of 'as Ref<something>' type assertions serves to prevent fetchedData from becoming Ref<UnwrapRef<something>>.
// This is a Vue-specific behavior. Although, I could opt for shallowRef, I prefer exhausting other possibilities first.
let temp;
if (defaultValue !== undefined) {
temp = ref(defaultValue) as Ref<T>;
} else {
temp = ref() as Ref<T | undefined>;
}
const fetchedData = temp; // Ref<T | undefined>
// Code utilizing this reference
return {
fetchedData,
};
}
Usage within a .vue component:
import useFetch from "@composables/useFetch";
import type { ICustomInterface } from "@types";
const { fetchedData } = useFetch<ICustomInterface[]>({
defaultValue: [],
});
fetchedData.value[0]; // ts18048: fetchedData.value is possibly undefined despite passing default value