Home > Software engineering >  React Custom Hook - Typescript for return value
React Custom Hook - Typescript for return value

Time:01-06

I have a custom hook, for example:

type DataItem {
    id: number
    title: string
}

const useDataItem = (uid: string) => {
    const {data, setData} = useState<DateItem>()
    const {loading, setLoading} = useState<boolean>(false)
    const {error, setError} = useState<number>()
    
   // ...do stuff

   return {data, loading, error}
}

In a test, I mock this hook using the following:

const mockDataItem = {
    loading: false,
    error: undefined,
    data: { id: 1, title: 'test' }
}
jest.mock("../../hooks/useDataItem", () =>
  jest.fn(() => mockUseDataItem)
);

I'm looking for a way to get the type of the hook's result, so I can apply it to mockDataItem (and not have to redeclare the type).

Is this possible, and if so then how?

CodePudding user response:

typeof useDataItem gives you the type of the function, and ReturnType<FunctionType> gives you the type of the function type's return value (docs), so: ReturnType<typeof useDataItem>

const mockDataItem: ReturnType<typeof useDataItem> = {
//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    loading: false,
    error: undefined,
    data: { id: 1, title: "test" },
};

Playground example (with various typos and issues with undefined from the question fixed)

CodePudding user response:

add a return type to the hook

export interface DataItemType {
   // properties
}

const useDataItem = (uid: string):DataItemType => {
....

const mockDataItem = {
    loading: false,
    error: undefined,
    data: DataItemType
}

CodePudding user response:

Yes, you can use the ReturnType utility type from the TypeScript library to extract the return type of the useDataItem function.

Here's how you can modify your code to extract the return type of useDataItem and apply it to mockDataItem:

import { ReturnType } from 'utility-types';

type DataItem = {
    id: number;
    title: string;
};

const useDataItem = (uid: string): ReturnType<typeof useDataItem> => {
    const { data, setData } = useState<DataItem>();
    const { loading, setLoading } = useState<boolean>(false);
    const { error, setError } = useState<number>();

    // ...do stuff

    return { data, loading, error };
};

const mockDataItem: ReturnType<typeof useDataItem> = {
    loading: false,
    error: undefined,
    data: { id: 1, title: 'test' },
};

jest.mock('../../hooks/useDataItem', () =>
    jest.fn(() => mockDataItem)
);

This will extract the return type of the useDataItem function and apply it to mockDataItem.

You can then use mockDataItem as the mock implementation for the useDataItem hook in your tests.

  • Related