2

I generated a typescript-node client of an API and I have something like this:

export declare class Api {

    getUser(username: string, email: string, idType: '1298' | '2309' | '7801')

}

I want to get the type of the third parameter in order to not have to recreate a type '1298' | '2309' | '7801' in my application.

I managed to make it work by doing:

type idType = Parameters<Api['getUser']>[2];

I'm not really satisfied by this solution, I would like to use key 'idType' and not his parameter's position.

How can I do this ?

Thanks.

5
  • 4
    Your solution is the only one. Parameters don't have names that can be observed from the type system Commented Jan 14, 2020 at 10:02
  • 1
    Instead of passing it around as such, what about defining a new type and then exporting it? So basically, doing the inverse of what you did. Commented Jan 14, 2020 at 10:03
  • There are no named parameters in TS. Well, there are, if the function receives a parameter as an object. getUser({idType: '1298' | '2309' | '7801'}) Commented Jan 14, 2020 at 10:20
  • @TitianCernicova-Dragomir Thanks, that That's what I thought. Commented Jan 14, 2020 at 10:51
  • @Terry the API class (and his function) is generated, I can't modify it because, on next generation, my modifications will be lost. This is like API is fixed and I have to do with. Commented Jan 14, 2020 at 10:51

2 Answers 2

1

What you are using is the right way. My answer will contain some playing around in order to achieve some better readability of such construct. Consider this as just an alternative solution.

function getUser(username: string, email: string, idType: '1298' | '2309' | '7801') { }

// utility types in order to achieve the goal
type ArgName = 'first' | 'second' | 'third'
type ArgNum<T extends ArgName> =
    T extends 'first' ? 0 :
    T extends 'second' ? 1 :
    T extends 'third' ? 2 :
    0

type ArgumentType
    <F extends (...a: any) => any, N extends ArgName> =
    Parameters<F>[ArgNum<N>]

type A = ArgumentType<typeof getUser, 'third'>; // '1298' | '2309' | '7801'

As you can see the main difference is that we are using some readable keys instead of numbers. For functions with bigger arity we can extend the keys.

For your particular case the usage would look like:

type IdType = ArgumentType<Api['getUser'], 'third'>; // '1298' | '2309' | '7801'
Sign up to request clarification or add additional context in comments.

Comments

0
export declare class Api {

    getUser(username: string, email: string, idType: IdType)

}

export type IdType = '1298' | '2309' | '7801';

1 Comment

Thanks for the answer but the API class (and his function) is generated, I can't modify it because, on next generation, my modifications will be lost.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.