Joj*_*oji 13 javascript typescript
我从d.tsAPI 文件中得到了这种类型
type EventConfigurations = {
Event1: {
Enabled?: boolean;
};
Event2: {
Enabled?: boolean;
};
Event3: {
Enabled?: boolean;
};
};
Run Code Online (Sandbox Code Playgroud)
现在我已经从该 API 调用的响应中返回了这些数据
const eventConfigurations: EventConfigurations = {
Event1: { Enabled: true },
Event2: { Enabled: false },
Event3: { Enabled: true }
};
Run Code Online (Sandbox Code Playgroud)
现在我想将数据映射到
enum EventDesc {
Event1 = "XXX",
Event2 = "YYY",
Event3 = "ZZZ"
}
type MyEvent = {
eventDesc: EventDesc;
topic: EventTopic;
};
const eventConfigurations: EventConfigurations = {
Event1: { Enabled: true },
Event2: { Enabled: false },
Event3: { Enabled: true }
};
const events: MyEvent[] = (Object.keys(eventConfigurations) as Array<
keyof EventConfigurations
>)
.map(
(eventType) =>
eventConfigurations[eventType].Enabled &&
({
eventDesc: EventDesc[eventType],
topic: EventTopic[eventType]
} as MyEvent)
)
.filter(Boolean);
Run Code Online (Sandbox Code Playgroud)
编译器抛出一个错误,指出可能events是
(false | MyEvent | undefined)[]
Run Code Online (Sandbox Code Playgroud)
但我.filter(Boolean);在最后补充说,它应该消除它是or 的map可能性。falseundefined
这是现场演示https://codesandbox.io/s/thirsty-yonath-ttdhn?file=/src/index.ts
jca*_*alz 12
TypeScript 的标准库确实有一个签名Array.prototype.filter(),可以缩小数组的类型,但只有当编译器将传入的回调识别为类型保护函数(其返回类型是形式的类型谓词)paramName is SomeType时,它才会使用该签名。而且,不幸的是,编译器当前无法推断回调(如Boolean或x => !!x)是类型保护;你必须这样注释它。
(有关使用某种控制流分析将某些函数解释为类型保护的功能请求,请参阅microsoft/TypeScript#16069 。)
这是一个带注释的回调:
const truthyFilter = <T>(x: T | false | undefined | null | "" | 0): x is T => !!x;
Run Code Online (Sandbox Code Playgroud)
或者,如果您确实想要,可以将其用作Boolean类型断言的实现,例如
const truthyFilter2 = Boolean as any as <T>(x: T | false | undefined | null | "" | 0) => x is T;
Run Code Online (Sandbox Code Playgroud)
这是一种通用的真实性检测器,尽管 TypeScript 并没有真正有一个好的方法来表示类型系统中所有可能的虚假值(NaN例如无法表示)。不管怎样,你可以看到它的实际效果,如下所示:
function fn(arr: Array<false | undefined | MyEvent>) {
const item = arr[0];
if (truthyFilter(item)) {
item.eventDesc; // okay, no error
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您将它与filter()编译器一起使用,则会按预期缩小范围:
const myEvents = arr.filter(truthyFilter)
// const myEvents: MyEvent[]
Run Code Online (Sandbox Code Playgroud)
您需要使用类型保护:
const filterUnwanted = (value: any): value is MyEvent => ('eventDesc' in value && 'topic' in value)
Run Code Online (Sandbox Code Playgroud)
或者不要Array#map跟随Array#filter,而是考虑Array#reduce:
const events = (Object.keys(eventConfigurations) as Array<keyof EventConfigurations>)
.reduce((acc, eventType) => (
eventConfigurations[eventType].Enabled ? acc.concat([{
eventDesc: EventDesc[eventType],
topic: EventTopic[eventType],
}]) : acc), [] as MyEvent[],
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6657 次 |
| 最近记录: |