typescript - TypeScript - 通过为属性提供不同的值来扩展类型
问题描述
我有一种类型:
export type EventItemType = {
Id: string;
Event?: any;
};
然后我有另一个类型,它最终将是值EventItemType.Event
:
export type FooEvent = {
Amount: number;
};
最终对象将是:
{
Id: 123,
Event: {
Amount: 1
}
}
稍后,我将遍历这些对象的数组:
events.map((event: EventItemType) => {
return {
someOtherKey: event.Event.Amount <-- how do I get TS to know this `Event` is of Type `FooEvent`
}
})
我有一堆对象创建为EventItemTypes
,但当时我不知道Event?: any;
类型,只有当我定义FooEvent
类型时。我该如何解决这个问题?
解决方案
// introduce generic type parameter Event
export type EventItemType<Event> = {
Id: string;
Event?: Event;
};
export type FooEvent = {
Amount: number;
};
// initialization with specific FooEvent
const events: EventItemType<FooEvent>[] = [];
events.map((event) => {
return {
someOtherKey: event.Event?.Amount // nicely shows proper type
}
})
最终,您可以执行以下操作以保持any
原始类型:
export type EventItemType = {
Id: string;
Event?: any;
};
export type FooEvent = {
Amount: number;
};
// function which takes array of some type T extending EventItemType
function processEvents<T extends EventItemType, F extends (event: T) => any>
(events: T[], f: F) { return events.map(f) };
const events = [{Id: '1', Event: {Amount: 1} as FooEvent}]
processEvents(events, event => ({
someKey: event.Event?.Amount // works nicely
}))
主要区别在于,在第二种解决方案中,我们具有非常多态的行为,并且第二个函数参数将调整为给定数组的类型。
工作推理的核心是:
T extends EventItemType
我们说我们得到不相等但扩展的类型,EventItemType
这意味着 TS 将缩小我们Event: any
的参数类型给定的范围F extends (event: T) => any
给定函数适用T
但也没有指定输出,但由于extend
函数输出也会缩小
推荐阅读
- java - 无法识别的字段“className”,@JsonTypeInfo
- c# - 将 Winform MS 图表另存为 SVG
- ios - Xcode 10“无法构建模块 Darwin / Foundation / CoreFoundation”等
- sql - access2016:sql查询以获取每个日期的总和
- android - 谷歌地图未显示在标签片段中
- azure - 是否可以在不停机的情况下将登台转换为生产?
- java - iText 2用不同的字体替换段落中的文本
- angular - 预计至少有 0 个参数,但得到了 2 个
- c - 检测文件中的字符并在 C 中拆分字节数组
- javascript - 使用带有 Typescript 的量角器获取所有元素属性?