接受TypeScript中的接口数组或单个接口

Accept Array of Interfaces OR single interface in TypeScript

本文关键字:接口 数组 单个 TypeScript 接受      更新时间:2023-09-26

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,但我不知道我所做的是否正确。有人能帮我吗?进一步的阅读材料或文档将是黄金。

使用TypeScript并集类型: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

您可以:

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

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