简体   繁体   中英

How to create a generic function with type declared externally in Typescript?

I have the following function (it is a React hook):

type HandleEditFn = (name: string) => (data: any) => React.MouseEventHandler;

type useFormToggleHook = (params: {
    forms: {
        [propName: string]: React.ReactType;
    };
    formPropsFn?: (data: any) => object;
    refetch?: any;
}) => [...];

export const useFormToggle: useFormToggleHook = ({
    ...
}) {

    const handleEdit : HandleEditFn = name => data => e => {
        ...
    }

    return [handleEdit];

}

Now, I want to make this function generic; so that, components who call this hook can do the following:

const [handleEdit] = useFormToggle<UserData>(...);

So, I added the generic syntax to types:

type HandleEditFn<T> = (name: string) => (data: T) => React.MouseEventHandler;

type useFormToggleHook<T> = (params: {
    forms: {
        [propName: string]: React.ReactType;
    };
    formPropsFn?: (data: T) => object;
    refetch?: any;
}) => [HandleEditFn<T>, ...];

// Type here doesn't work
export const useFormToggle: useFormToggleHook<T> = ({
    ...
}) {

    // Type is required here!
    const handleEdit : HandleEditFn<T> = name => data => e => {
        ...
    }

    return [handleEdit, ...];

}

When I add useFormToggleHook<T> for useFormToggle function, I get an error that T is not a valid type.


I have read the following Stackoverflow post: TypeScript Type of generic function but this did not answer my question. I know that I can do the following:

export const useFormToggle : <T>(params: {
    forms: {
        [propName: string]: React.ReactType;
    },
    formPropsFn?: (data: any) => object;
    refetch?: any;
}) = ({ ... }) => ...

However, I want to declare the type for the function separately. Is this possible with Typescript?

You have to declare your generic type somewhere to make it work.

type HandleEditFn makes HandleEditFn generic and whatever is passed to it, will be T.

Your problem is, that you do not pass an actual type to HandleEditFn with:

 const handleEdit : HandleEditFn<T> = name => data => e => {}

because T is not a type which is declare somewhere.

To make it work and to declare T in HandleEditFn you have to call it like this:

const handleEdit : HandleEditFn<string> = name => data => e => {}

This will make data string for example but you can pass any type or interface to define T and use it as data.

The same applies to useFormToggleHook:

export const useFormToggle: useFormToggleHook<string> = ()

Hope this helps. Happy coding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM