TypeScript 接口/函数签名类型

Jus*_*tin 8 typescript

为了更好的可读性,我试图找到一种在函数声明之外直观地声明 TypeScript 函数参数的简写方式。我目前有这个功能:

function processPerson(firstName: string, lastName: string, age: number, city: string, country: string, yetAnotherArgument: string) {}
Run Code Online (Sandbox Code Playgroud)

(请注意,我不希望创建对象并将其传递给函数)。有没有办法让我像这样指定函数参数?

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

function doSomething(...arguments: MyArguments) {}
Run Code Online (Sandbox Code Playgroud)

Mah*_*ary 10

我想这是最好的:

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


const processPerson : MyFunction = (firstName, lastName,
 age, city, country, yetAnotherArgument) => {}
Run Code Online (Sandbox Code Playgroud)

您也可以在Typescript Playground中使用此代码。


jca*_*alz 5

您可以使用元来表示参数列表,如下所示:

type PersonArgs39 = [string, string, number, string, string, string];
function processPerson39(...args: PersonArgs39) {}
Run Code Online (Sandbox Code Playgroud)

但这并没有为调用签名参数提供有意义的名称:

// function processPerson39(args_0: string, args_1: string, 
//   args_2: number, args_3: string, args_4: string, args_5: string): void
Run Code Online (Sandbox Code Playgroud)

从 TypeScript 4.0 开始,您将能够使用标记/命名元组元素,它允许您向编译器提示参数名称应该是什么:

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
Run Code Online (Sandbox Code Playgroud)

不过,这只为调用签名提供了有意义的名称。在实现内部,您有一个参数数组,其元素只能按位置访问,而不能按名称访问。标记元组中的名称只是提示,不会出现在运行时代码中:

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

您尝试使实现访问名称所做的任何操作都必然涉及冗余,因为您发现除了调用签名标签的名称之外,您还指定了运行时代码的名称:

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
}
Run Code Online (Sandbox Code Playgroud)

我不知道args[personArgNames.age]是否值得。我可以想象编写一个函数来转换args为一个对象,该对象的属性是您要使用的名称,但这开始接近仅使用对象作为参数,而您不想这样做。所以我认为这已经是我能达到的最接近你想要完成的目标了。


好的,希望有帮助;祝你好运!

Playground 代码链接