如何解决Typescript:通过添加具有特定命名的新字段来动态扩展接口
我有一个这样的界面:
interface ProjectCostData {
purchasePrice: number;
propertyValue: number;
recentlyDamaged: boolean;
}
现在,我想基于上面的界面动态创建这样的界面:
interface ProjectCostDataWithSetters {
purchasePrice: number;
setPurchasePrice: Dispatch<SetStateAction<number>>;
propertyValue: number;
setPropertyValue: Dispatch<SetStateAction<number>>;
recentlyDamaged: boolean;
setRecentlyDamage: Dispatch<SetStateAction<boolean>>;
}
->映射到第一个界面,并为每个条目A添加一个新的条目B,其键为`set $ {entryKey}`,并且类型可以从条目A派生。
在TS中可以吗?
背景:我有一个基于OpenAPI的后端,该后端为我提供了.yaml
文件的API结构。我通过生成器传递该文件,并接收与API通讯的接口和函数。在前端,我使用反应上下文来构建全局状态。我想基于生成器的输出构建全局反应上下文。
解决方法
在打字稿4.0或更早版本中,这是不可能的。字符串,包括属性名称,要么完全称为常量(即<div ref={this.container}>
<ul ref={this.list}>
{mounted && items.map((item,index) => this.renderItem({ index,item,maxIndex }))}
</ul>
</div>
),要么是一组有限的常量(例如"foo"
)之一,或者只是具有任何内容的任何字符串({{1 }}。因此,您不能基于其他属性名称构造新的属性名称。
但是,Typescript 4.1(当前为Beta)具有一些功能,可能在template literal types
中有帮助"foo" | "bar"
那个:
string
有点时髦。 This PR explains that better than I could.
您甚至可以处理大写更改:
interface ProjectCostData {
purchasePrice: number;
propertyValue: number;
recentlyDamaged: boolean;
}
// Create a new setter property for each key of an interface
type WithSetters<T extends { [k: string]: any }> = T & {
[K in keyof T & string as `set_${K}`]: (newValue: T[K]) => void
}
// Testing
declare const obj: WithSetters<ProjectCostData>
obj.purchasePrice // number
obj.set_purchasePrice(123) // (newValue: number) => void
将所有内容放在一起会有些棘手,尤其是在beta版中。但我认为,从理论上讲,所有这些因素都可以实现这种类型转换。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。