Параметры функции Typescript - PullRequest
       14

Параметры функции Typescript

1 голос
/ 27 сентября 2019

Я сталкиваюсь со сценарием, в котором у меня есть много функций с похожими параметрами, и я пытаюсь найти решение, чтобы сделать все легко обслуживаемым.Возьмите следующий пример:

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

Изначально я думал о таком интерфейсе, как:

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

и использовал его в функции:

public func1(args: IMyInaterface) {

}

Нозатем в функции 4,5,6 я не могу расширить его, чтобы принимать N дополнительных аргументов без создания новых интерфейсов, и я не хочу поддерживать все производные интерфейсы.

Я также хотел бы сохранить свои наборы (не все параметры являются строками, а все функции имеют определенное количество параметров), чтобы что-то вроде

func1(...args: string){}

не работало

Есть идеи, как лучше это сделать?

Ответы [ 4 ]

3 голосов
/ 27 сентября 2019

в функции 4,5,6 Я не могу расширить его, чтобы принимать N дополнительных аргументов без создания новых интерфейсов

На самом деле вы можете использовать тип пересечения для расширенияинтерфейс "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
1 голос
/ 27 сентября 2019

Начиная с TypeScript 3.0 мы можем представлять списки параметров функции в виде типов кортежей .Таким образом, ваш вариант использования может поддерживаться чем-то вроде этого:

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
}

Вы можете видеть, что IntelliSense показывает методы как имеющие различные параметры, такие как param_0, param_1 и т. Д.


Вы также можете настроить 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
}

Хорошо, надеюсь, это поможет.Удачи!

Ссылка на код

1 голос
/ 27 сентября 2019

Вы можете использовать знак вопроса "?"представлять, нужна ли переменная или нет, например:

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

В этой функции вы можете передать 0, 1, 2, 3 или 4 параметра.

0 голосов
/ 27 сентября 2019

Хорошо, насколько я вижу, у вас есть два варианта .

Первый: вы можете создать интерфейс со всеми параметрами, которые функции должны иметь в качестве базы, изатем передайте объект с дополнительными атрибутами.то есть:

interface BaseParams {
  param1: string
  param2: string
}

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

Здесь ключ заключается в том, чтобы не добавлять объект params в состав BaseParams, тогда вы можете создать такую ​​функцию:

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

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

Typescriptоценивать, только если передаваемый объект имеет поля из интерфейса, который вы создали.

Другой и менее известный вариант - использовать Partial из Typescript, он делает все атрибуты, которые вы объявили в интерфейсе,быть необязательным, поэтому вам не нужно будет передавать каждый параметр как param1?: string.В этом порядке вы должны создать интерфейс со всеми возможными параметрами.

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

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