网站搜索

TypeScript 多类型定义


我已经在一个 d.ts 文件中定义了 interface:

declare module myModule
{
    interface IQedModel {
        field: string | string[];
        operator: string;

    }
}

在一个 Angular 控制器中,我已经实现了它:

vm.filters = <myModule.IQedModel>{
    operator: 'and',
    field: []
};

function populateFields() {
    vm.filters.field = [];

    angular.forEach(addedFilters, item => {
        vm.filters.field.push(item.data); //<-- THIS LINE SHOWS ERRORS
    });
}

错误是:

属性 'push' 在类型 'string | string[]' 上不存在

这里的问题是什么?

答案#1

你可以使用泛型:

declare module myModule
{
    interface IQedModel<T> {
        field: T;
        operator: string;

    }
}

var filters = <myModule.IQedModel<Array<string>>>{
    operator: 'and',
    field: []
};

var filters2 = <myModule.IQedModel<string>>{
    operator: 'and',
    field: ""
};

filters.field.push(""); // works
// filters.field = "" // String not assignable to string[]


filters2.field = ""; // works
// filters2.field.push(""); // push does not exist on type string

或者:

declare module myModule
{
    interface IQedModel<T> {
        field: T;
        operator: string;

    }

    interface ISingleFieldQedModel extends IQedModel<string> {}
    interface IMultiFieldQedModel extends IQedModel<string[]> {}
}

var filters = <myModule.IMultiFieldQedModel>{
    operator: 'and',
    field: []
};

filters.field.push("");
// filters.field = "" // String not assignable to string[]


var filters2 = <myModule.ISingleFieldQedModel>{
    operator: 'and',
    field: ""
};

filters2.field = "";
// filters2.field.push(""); // push does not exist on type string

你也可以使用类型保护,看看这个,但目前有一些问题。

答案#2

所以根据 BGR 的评论,我需要先转换成数组:

(<string[]>vm.filters.field).push(item.data);