如何为只有一个数组作为第一个参数或元素的扩展的函数写入BODY

时间:2017-08-27 20:10:50

标签: typescript

这是this question

的副产品

我想编写将保留此声明的所有属性的函数体

declare function myFunc(...configuration: Configuration[]): Output;
declare function myFunc(configuration: Configuration[]): Output;

这就是我们离开@ shaun-luttin

的地方
class Configuration {
  public context: any;
  public entry: any;
  public output: any;
}

enum Output {
  WasSpead,
  WasOneArray
}

function myFunc(...configuration: Configuration[]): Output { 
  return Output.WasSpead
};
function myFunc(configuration: Configuration[]): Output {
  return Output.WasOneArray
};

const conf = new Configuration;
const confs = [conf];

const r1: Output = myFunc(confs); // right
const r2: Output = myFunc(conf); // right
const r3: Output = myFunc(conf, conf); // right
console.log(r1 === Output.WasOneArray, r2 === Output.WasSpead, r3 === Output.WasSpead)

//const f1: Output = myFunc(confs, confs); // must fail, cause can accept only one array
//const f2: Output = myFunc(conf, confs); // must fail, cause or array, or spread
//const f3: Output = myFunc(confs, conf); // must fail, same
//const f4: Output = myFunc(""); // must fail, wtf

Playable example

更新(我的impl)

function myFunc(...configuration: Configuration[]): Output;
function myFunc(configuration: Configuration[]): Output;
function myFunc(...configuration): Output {
  if (Array.isArray(configuration[0])) return Output.WasOneArray
  return Output.WasSpead
};

UPDATE2

通过界面

如果你有多个具有相同类型的函数,那就很好了,将它们定义为const并设置相同类型真的很简洁

class Configuration {
  public context: any;
  public entry: any;
  public output: any;
}

enum Output {
  WasSpead,
  WasOneArray
}


interface Outputter {
  (...configuration: Configuration[]): Output;
  (configuration: Configuration[]): Output;
}

const myFunc: Outputter = (...configuration) => {
  if (Array.isArray(configuration[0])) return Output.WasOneArray
  return Output.WasSpead
}

const myFuncDeceiver: Outputter = (...configuration) => {
  if (Array.isArray(configuration[0])) return Output.WasSpead
  return Output.WasOneArray
}

const conf = new Configuration;
const confs = [conf];

const r1: Output = myFunc(confs); // right
const r2: Output = myFunc(conf); // right
const r3: Output = myFunc(conf, conf); // right
console.log(r1 === Output.WasOneArray, r2 === Output.WasSpead, r3 === Output.WasSpead)

//const f1: Output = myFunc(confs, confs); // must fail, cause can accept only one array
//const f2: Output = myFunc(conf, confs); // must fail, cause or array, or spread
//const f3: Output = myFunc(confs, conf); // must fail, same
//const f4: Output = myFunc(""); // must fail, same

1 个答案:

答案 0 :(得分:1)

  

如何为只有一个数组作为第一个参数或元素扩展的函数写入BODY。

功能重载

我们可以使用函数重载。诀窍是与函数体分开定义函数重载签名。

class Configuration {
  public context: any;
  public entry: any;
  public output: any;
}

enum Output {
    WasOneItem, 
    WasMultipleItems,
}

function myFunc(...configuration: Configuration[]): Output;
function myFunc(configuration: Configuration[]): Output;
function myFunc(...configuration) 
{
    if (configuration.length) {
        return Output.WasMultipleItems;
    }

    return Output.WasOneItem;
};

注意:我们可以确定输入是一个还是多个项目,但我们无法确定它是通过数组还是传播来输入。

功能类型接口

正如您所理解的那样,我们也可以使用接口和箭头功能。

interface Func { 
     (...configuration: Configuration[]): Output;
    (configuration: Configuration[]): Output;
}

const myFunc: Func = (...configuration) => { 
    if (configuration.length) {
        return Output.WasMultipleItems;
    }

    return Output.WasOneItem;
}