创建一个变量[x[0] or x[1] for x in result]
,当我没有数据时,我希望它是假的,否则就是一个对象数组。所以我做了一个联合类型:notifications
很好,除非我let notifications: object[] | boolean = [];
我得到了
notifications.push(notification);
是的,TS不确定它是一个数组。我会告诉它。 Property 'push' does not exist on type 'boolean | object[]'.
Property 'push' does not exist on type 'true'.
同样的错误。更多的挖掘,意识到警卫工作正常,只有当我的notifications = [];
内部lodash' .push
我得到错误。
现状:
_forEach
一系列不同的防护方式。不明白let notifications: object[] | boolean;
if (noNotifications) {
notifications = false;
} else {
notifications = [];
_forEach(notificationsObj, function (notification, type) { // Culprit
notification['type'] = type;
notifications.push(notification); // <-- TS error on push
});
}
return notifications;
打破它的原因,所以不确定下一步该尝试什么。
是否可以在_forEach
内的变量上使用push
?如果是这样,怎么样?
答案 0 :(得分:3)
TypeScript不能很好地理解_forEach
,知道在运行回调中的代码之前不会重新分配notifications
。由于notifications
不是const
,因此TypeScript认为可能可以重新分配它。 TypeScript如何进行基于类型的控制流分析有很多tradeoffs;缩小传播到闭包的类型很难。由于您无法真正让TypeScript遵循控制流程,因此您有以下几种选择:
最简单的方法就是在执行notifications
时断言push()
是一个数组:
_forEach(notificationsObj, function(notification, type) { // Culprit
notification['type'] = type;
(notifications as object[]).push(notification); // assertion
});
这个断言是你告诉编译器不要担心。
为了获得更多的类型安全性而牺牲一点运行时分配混乱,引入const
变量,然后将其分配给notifications
:
const notificationsArray: object[] | boolean = []; // cannot be reassigned
_forEach(notificationsObj, function(notification, type) { // Culprit
notification['type'] = type;
notificationsArray.push(notification); // no error
});
notifications = notificationsArray; // assignment works
这里TypeScript知道永远不能重新分配notificationsArray
,所以它的类型一直缩小到object[]
一直到回调。然后,您可以将其值分配给notifications
。 (您也可以声明notificationsArray
只是输入object[]
,然后不要| boolean
。我只是表明const
会影响缩小范围。)
希望您理解并且其中一种解决方案适合您。祝你好运!
答案 1 :(得分:1)
jcalz的答案解决了您的具体问题,但我只是想提供一种解决问题的不同方法。通过以功能样式编写,您可以完全避免许多这些问题。
import * as _ from 'lodash';
function getNotifications(notificationsObj: {[type: string]: object}): object[] | boolean {
if (_.isEmpty(notificationsObj)) {
return false;
} else {
// note: lodash map will turn an object into an array
return _.map(notificationsObj, (notification, type) => {
return {...notification, type};
});
}
}
注意我也避免改变原始通知对象,与原始解决方案形成对比。如果您依赖于发生的突变,那么您应该更改该部分。