【问题标题】:Accept Array of Interfaces OR single interface in TypeScript [duplicate]接受 TypeScript 中的接口数组或单个接口 [重复]
【发布时间】:2017-02-07 12:56:31
【问题描述】:

在 TypeScript 中真的很新。我有一组预设,用户可以添加或修改现有预设。因为它只有几个键,所以我做了一个界面。

interface IStylePreset {
    type : string;
    backgroundColor : string;
    color? : string
}

实现在这里:

static stylePresets : Array<IStylePreset> = [
    { type: "default", backgroundColor: "#37474f" , color: "#ECEFF1"},
    { type: "success", backgroundColor: "#37474f", color: "#ECEFF1" },
    { type: "error", backgroundColor: "#d32f2f", color: "#EEE"}
];

现在我有一个配置函数,它采用自定义预设来更改现有预设或添加新预设。

static config = {
    types(newPresets) : void {
        newPresets = [].concat(newPresets);
        for(var i = 0, len = newPresets.length, current; i< len; i++){
            var pos = Message.Util.find(Message.stylePresets, newPresets[i].type)
            current = newPresets[i];
            if(pos !== -1) for(var key in current) Message.stylePresets[pos][key] = current[key];
            else Message.stylePresets[Message.stylePresets.length] = current;
            }
        }
    };

问题是,我不知道在 newPresets 的类型中指定什么,因为它既接受对象数组,也接受单个对象(这构成单个元素数组 newPresets = [].concat(newPresets);) .

我正在尝试学习 TypeScript,但我不知道我所做的是否正确。有人可以帮我吗?进一步阅读材料或文档将是黄金。

【问题讨论】:

  • 有人指出这个问题是重复的,所以我投了反对票。

标签: javascript arrays typescript interface


【解决方案1】:

你可以:

1) 像这样使用any 类型:types(newPresets : any)

2) 保持IStylePreset[] 类型(例如types(newPresets : IStylePreset[]) 并在传递单个对象时将其包装在这样的数组中:config.types([{ type: "default", backgroundColor: "#37474f" , color: "#ECEFF1"}]);

【讨论】:

  • 谢谢。我试图避免任何。我想我可能已经通过使用 types(newPresets : IStylePreset | Array) : void {... 编译器说它干净但我不知道这是否正确.. 你能确认一下吗?
  • 从方法签名的角度来看,这听起来不错。另外,我刚刚看到您的问题实际上已经在这里得到了回答:stackoverflow.com/questions/35749833/…
  • 刚看到。谢谢!
【解决方案2】:

使用 TypeScript union type: IStylePreset | IStylePreset[]

在函数体中,您可以使用Array.isArray() 检查是否传递了数组或单个实例。实际上,在这种情况下,concat() 已经在内部检查了数组或实例是否被连接,因此解决方案很简单:

例如:

class Config {
    private presets: IStylePreset[] = [];

    public addPresets(presetOrArray: IStylePreset | IStylePreset[]) {
        // Concat will concat either Array or instance
        this.presets = this.presets.concat(presetOrArray);
    }

    public getPresets(): IStylePreset[] {
        return this.presets;
    }
}

let config = new Config();
config.addPresets(stylePresets);
config.addPresets(stylePresets[0]);
console.log(config.getPresets().length); // prints 4

【讨论】:

  • 谢谢!我实际上是在考虑同样的问题。但是当我可以选择 [].concat 时,我会尽量避免使用 isArray。它在 chrome 上的速度提高了 43%,而且我们保持干燥,因为除了一些更改之外,if 和 else 中的代码都是相同的。您能否确认 types(newPresets : IStylePreset | Array) 是否有效?编译器说它很干净,但我仍然不确定它是否正确..尝试查看文档但找不到..
  • 是的,IStylePreset[] 和 Array 只是同一事物的两种不同表示法。关于连接的好点。它实际上比推入 forEach 循环更有效。我已经相应地修改了上面的例子。您仍然需要 isArray 来检查是否传递了数组或单个实例。
  • 如果单个实例被传递,concat 会将它变成一个数组。如果传递了一个数组,则 [].concat 不会导致任何更改。 +1 回答。过一段时间会接受它,看看是否有更好的性能解决方案。谢谢大佬!
  • 感谢您指出这一点。一个新人在回答问题时停止学习新事物......在这种情况下,对 isArray 的调用确实是不必要的。示例改编。
猜你喜欢
  • 2016-06-26
  • 2019-04-27
  • 1970-01-01
  • 2019-01-13
  • 2014-07-25
  • 2015-10-16
  • 2022-01-21
  • 2022-12-06
相关资源
最近更新 更多