简体   繁体   English

Typescript function参数

[英]Typescript function parameters

I'm encountering a scenario where I have many functions with similar parameters and struggling to find a solution to make everything easily maintainable.我遇到了一个场景,我有许多具有相似参数的函数,并且努力寻找一种解决方案来使一切都易于维护。 Take the following example:举个例子:

public func1(param1: string, param2: string, param3: string){}
public func2(param1: string, param2: string, param3: string){}
public func3(param1: string, param2: string, param3: string){}

public func4(param1: string, param2: string, param3: string, param4: string){}
public func5(param1: string, param2: string, param3: string, param4: string){}
public func6(param1: string, param2: string, param3: string, param4: string){}

... Etc

Initially I was thinking about an interface such as:最初我在考虑一个接口,例如:

interface IMyInterface {
  param1: string;
  param2: string;
  param3: string;
}

and using it in the fuction:并在功能中使用它:

public func1(args: IMyInaterface) {

}

But then in fuction 4,5,6 I can't really extend it to accept N number of additional args without creating new interfaces and I don't want to maintain all the derived interfaces.但是在功能 4,5,6 中,我不能真正扩展它以接受 N 个附加参数而不创建新接口,我不想维护所有派生接口。

I'd also like to keep my typings (not all parameters are strings and all functions have a defined number of parameters) so something like我还想保留我的打字(并非所有参数都是字符串,所有函数都有定义数量的参数)所以像

func1(...args: string){}

wouldn't work行不通

Any Idea how best to go about this?任何想法如何最好地 go 关于这个?

in function 4,5,6 I can't really extend it to accept N number of additional args without creating new interfaces在 function 4,5,6 中,我不能真正扩展它以接受 N 个附加参数而不创建新接口

Actually, you could use an intersection type to extend an interface "inline":实际上,您可以使用交集类型来扩展接口“内联”:

interface BaseArgs {
    foo:string, 
    bar: number
}

function func1(a: BaseArgs) {}
function func2(a: BaseArgs & {more: boolean}) {}

func1({foo: "aa", bar: 3}) // ok
func2({foo: "aa", bar:3, more: true}) // ok

You can use the question mark "?"您可以使用问号“?” to represent if a variable is necessary or not, for instance:表示变量是否必要,例如:

public func4(param1?: string, param2?: string, param3?: string, param4?: string){}

In this function you can pass 0, 1, 2, 3 or 4 params.在此 function 中,您可以传递 0、1、2、3 或 4 个参数。

Since TypeScript 3.0 we've been able to represent function parameter lists as tuple types .自 TypeScript 3.0 以来,我们已经能够将function 参数列表表示为元组类型 So your use case can be supported by something like this:所以你的用例可以得到这样的支持:

type ThreeStrings = [string, string, string];
type FourStrings = [string, string, string, string];

class Blarg {
  public func1(...param: ThreeStrings) {}
  public func2(...param: ThreeStrings) {}
  public func3(...param: ThreeStrings) {}
  //(method) Blarg.func3(param_0: string, param_1: string, param_2: string): void

  public func4(...param: FourStrings) {}
  public func5(...param: FourStrings) {}
  public func6(...param: FourStrings) {}
  // (method) Blarg.func6(param_0: string, param_1: string, param_2: string, param_3: string): void
}

You can see that IntelliSense shows the methods as having distinct parameters like param_0 , param_1 , etc.您可以看到 IntelliSense 将方法显示为具有不同的参数,例如param_0param_1等。


You can also have IntelliSense keep track of parameter names by using the following notation:您还可以使用以下表示法让 IntelliSense 跟踪参数名称:

type OtherParams = Parameters<
  (name: string, age: number, likesAsparagus: boolean) => void
>;


class Blarg {
  public func7(...param: OtherParams) {}
  public func8(...param: OtherParams) {}
  public func9(...param: OtherParams) {}
  // (method) Blarg.func9(name: string, age: number, likesAsparagus: boolean): void
}

Okay, hope that helps.好的,希望有帮助。 Good luck!祝你好运!

Link to code 链接到代码

Alright, so far as I can see you have two options .好吧,据我所知,您有两个选择

The first one: you can create an interface with all the parameters that the functions must have as a base and then pass an object with the additional attributes.第一个:您可以使用函数必须具有的所有参数作为基础创建一个接口,然后传递一个带有附加属性的 object。 ie: IE:

interface BaseParams {
  param1: string
  param2: string
}

const params = {
  param1 = 'the 3rd'
  param2 = 'is'
  param3 = 'additional'
}

The key here, is to not add the params object to be part of BaseParams , then you can create the function like this:这里的关键是不要将参数 object 添加为BaseParams的一部分,然后您可以像这样创建 function :

const funct = (params: BaseParams) => {
...
}

//call it with the object you created
funct(params)

Typescript will only evaluate if the object you are passing has the fields from the interface you created. Typescript 将仅评估您传递的 object 是否具有您创建的接口中的字段。

The other option and the less known is to use Partial from Typescript, it makes all the attributes you declared in the interface to be optional, so you won't have to pass each param like param1?: string .另一个不太为人所知的选项是使用 Typescript 中的Partial ,它使您在接口中声明的所有属性都是可选的,因此您不必像param1?: string那样传递每个参数。 In this order, you have to create an interface with all the possible params.按照这个顺序,您必须创建一个包含所有可能参数的接口。

interface Params {
 param1: string
 param2: string
 param3: string
 param4: string
 paramN: string
}

const funct = (params: Partial<Params>) => {
...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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