简体   繁体   中英

TypeScript Interface / Type for Function Signature

For better readability, I'm trying to find a shorthand for visually declaring TypeScript function arguments outside of function declaration. I currently have this function:

function processPerson(firstName: string, lastName: string, age: number, city: string, country: string, yetAnotherArgument: string) {}

(Please note, I do not wish to create and pass an object to function). Is there a way for me to specify the function args like this?

type MyArguments = {
  firstName: string,
  lastName: string,
  age: number,
  city: string,
  country: string,
  yetAnotherArgument: string
}

function doSomething(...arguments: MyArguments) {}

You can use a tuple to represent a parameter list, like this:

type PersonArgs39 = [string, string, number, string, string, string];
function processPerson39(...args: PersonArgs39) {}

This doesn't give the call signature arguments meaningful names, though:

// function processPerson39(args_0: string, args_1: string, 
//   args_2: number, args_3: string, args_4: string, args_5: string): void

Starting in TypeScript 4.0 you will be able to use labeled/named tuple elements which allows you to give hints to the compiler for what the names of the arguments should be:

type PersonArgs = [firstName: string, lastName: string, 
  age: number, city: string, country: string, yetAnotherArgument: string];
function processPerson(...args: PersonArgs) {}
// function processPerson(firstName: string, lastName: string, 
//   age: number, city: string, country: string, yetAnotherArgument: string): void

This only gives meaningful names to the call signature , though. Inside the implementation, you have an array of arguments, whose elements can only be accessed positionally and not by name. The names in labeled tuples are just hints, and do not make it to the runtime code:

function processPersonImpl(...args: PersonArgs) {
  args.age.toFixed(); // error!  property age does not exist
  args[2].toFixed(); // okay, args[2] is a number
}

Anything you do to try to make the implementation get access to the names will necessarily involve redundancy, as you find yourself specifying the names for the runtime code in addition to the names for the call signature labels:

const personArgNames = { firstName: 0, lastName: 1, age: 2, 
  city: 3, country: 4, yetAnotherArgument: 5 } as const;
function processPersonImpl2(...args: PersonArgs) {
  args[personArgNames.age].toFixed(); // okay, I guess
}

I'm not sure args[personArgNames.age] is even worth it. I could imagine writing a function to convert args to an object whose properties are the names you want to use, but this is starting to get close to just using an object as the parameter, which you don't want to do. So I think this is as close as I can get to what you're trying to accomplish.


Okay, hope that helps; good luck!

Playground link to code

I guess this's as best as it can get:

type MyFunction = ( 
  firstName: string,
  lastName: string,
  age: number,
  city: string,
  country: string,
  yetAnotherArgument: string) => void


const processPerson : MyFunction = (firstName, lastName,
 age, city, country, yetAnotherArgument) => {}

You can play with this code in Typescript playground too.

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