我有一个函数,其中input
是Dictionary或Dictionaries数组:
public convert(input: IDictionary<any> | IDictionary<any>[], additionalProps?: string[]) {
if ( input instanceof Array ) {
this._handlers.forEach(fn => {
input = input.map(i => fn(i));
});
return input.map(i => this._convert(i, additionalProps));
} else {
this._handlers.forEach(fn => {
input = fn(input);
});
return this._convert(input, additionalProps);
}
}
该函数执行我需要的功能但是Typescript没有正确识别 if 块中的input
引用总是将成为一个数组,因此它给出了以下错误:
“IDictionary”
类型中不存在“地图”属性
我会想到使用Typescript 2.x它会使用if块作为其控制流分析的一部分来确定联合类型现在只能是IDictionary<any>[]
类型。我的理解错了吗?有没有正确的方法来表明这一点?
P.S。我正在使用Typescript 2.1.4
处理程序的其他一些背景信息:
export default class Mapper {
private _handlers: Function[] = [];
使用以下公共接口设置和处理程序:
public handlers(fn: Function | Function[]) {
if(fn instanceof Array) {
this._handlers.concat(fn);
} else {
this._handlers.push(fn);
}
return this;
}
可以在此gist中找到整个班级。 mapper类的一个示例用法是......
const mapping: IMapping = {
id: 'invoiceId',
type: (context) => context['type'] === 'ACCREC' ? 'accounts-receivable' : 'accounts-payable',
date: (context) => xero.xeroDate(context['date']),
dueDate: (context) => xero.xeroDate(context['dueDate']),
lastUpdated: (context) => xero.xeroDate(context['updatedDateUtc']),
payments: (context) => context['payments'].map((p: IDictionary<any>) => p['PaymentID']),
prePayments: (context) => context['prepayments'].map((p: IDictionary<any>) => p['PaymentID']),
overPayments: (context) => context['overpayments'].map((p: IDictionary<any>) => p['PaymentID'])
};
const mapper = new Mapper(mapping);
return mapper
.handler(utils.camelCaseProperties)
.convert(invoices);
最后,IDictionary
定义为:
interface IDictionary<T> {
[key: string]: T;
};
答案 0 :(得分:1)
问题是您要在两个不同的地方更改input
的类型:
input = input.map(i => fn(i));
和
input = fn(input);
你可以这样做:
public convert(input: IDictionary<any> | IDictionary<any>[], additionalProps?: string[]) {
let input2;
if ( input instanceof Array ) {
this._handlers.forEach(fn => {
input2 = input.map(i => fn(i));
});
return input2.map(i => this._convert(i, additionalProps));
} else {
this._handlers.forEach(fn => {
input2 = fn(input);
});
return this._convert(input2, additionalProps);
}
}
或者将_handler
的类型更改为:
private _handlers = [] as Array<() => IDictionary<any>[]>;
答案 1 :(得分:0)
if ( input instanceof Array ) {
let inputArray = <IDictionary<any>[]> input;
this._handlers.forEach(fn => {
inputArray = inputArray.map(i => fn(i));
});
// ...
}