简体   繁体   中英

Can I pass a function (and get its ReturnType) to a generic TypeScript type?

So my code is as follows. Ideally I'd like to achieve the following as a type: LoginPayload<login> .

I can't figure out the constructs to pass in any function as a generic parameter and get its return type.

export type LoginPayload = ReturnType<typeof login>

const login = createAction('customer/login', function prepare({ username, password }: LoginRequest) {
  return { payload: { username, password } }
})

What I'd like to achieve:

export type LoginPayload<F> = ReturnType<typeof F>

const login = createAction('customer/login', function prepare({ username, password }: LoginRequest) {
  return { payload: { username, password } }
})

//use: LoginPayload<login>

Any help is much appreciated.

Not sure, if that is what you are seeking, but I'll give it a try:

Assuming you use redux-actions package, the return type of login (the function created by invoking createAction ) will be Action<Payload> . Payload is a type parameter, which is inferred from the return type of the passed in callback prepare .

Action (from redux-actions):

export interface BaseAction {
    type: string;
}

export interface Action<Payload> extends BaseAction {
    payload?: Payload;
    error?: boolean;
}

If you cannot use an explicit, known type for the prepare callback return type, Payload can be inferred like this (assumes string type for user + pw in the example):

type InferPayload<T> = T extends Action<infer I> ? I : never

/*
type Payload = {
    payload: {
        username: string;
        password: string;
    };
}
*/
type Payload = InferPayload<ReturnType<typeof login>>

So all in all Action<Payload> will have this type:

{
    payload?: {
        payload: {
            username: string;
            password: string;
        };
    } | undefined;
    error?: boolean | undefined;
    type: string;
}

Playground

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