typescript - 打字稿:将属性添加到类中以替代类型
问题描述
我有一个类型是字符串的析取:
export type Category = 'people' | 'projects' | 'topics' | 'tools'
我将索引声明为:
interface Entry {
...
}
type IPostEntryIndex = {
[name in Category]: Entry
}
如何声明与类别名称对应的类属性?
const categories: Category[] = ['people', 'projects', 'topics', 'tools']
class PostEntryIndex implements IPostEntryIndex {
// what goes here so that `PostEntryIndex` has an attribute
// for each category in Category?
constructor () {
categories.map(cat => this[cat] = new Entry())
}
}
更新:当然,我可以简单地明确声明类别。我正在寻找的是一个 DRY 答案,如果我添加一个类别,则不需要更新。(注意使categories
数组不重复Category
也很好。我想我可以为此使用枚举。)
解决方案
据我所知,没有在一个类中声明一堆属性的语法。您可以通过这种方式添加索引签名,但不能添加字符串文字的联合。显然您可以手动添加它们,但我认为重点是您不想这样做。
您可以做的一件事是使用声明合并将属性添加到类实例的接口中。当你编写class PostEntryIndex {}
它时,它会创建一个名为的值PostEntryIndex
,它是一个类构造器,以及一个名为对应于类索引的接口。PostEntryIndex
你可以使用接口合并来添加你想要的任何属性......像这样:
interface PostEntryIndex extends IPostEntryIndex { }
class PostEntryIndex {
constructor() {
categories.map(cat => this[cat] = new Entry())
}
}
请注意,这样做会绕过模式附带的严格的类属性初始化检查--strict
,因此您不能依赖编译器来抱怨未初始化的属性。(这实际上是为了您的优势,因为编译器不理解循环categories
用于初始化所有相关属性。)
另请注意,一旦以这种方式合并接口,该implements
子句就特别多余,因此我将其删除。(事实证明,implements
子句从来都不是真正必要的;TypeScript 的结构类型系统不需要您声明A implements B
使用A
as a B
,只要它们具有兼容的结构......但我离题了)
无论如何,让我们看看它是否有效:
const pei = new PostEntryIndex();
pei.projects; // Entry
看起来不错。好的,希望有帮助;祝你好运!
推荐阅读
- python - 消费者可以从存储特定键值数据的分区中读取记录吗?
- ruby-on-rails - 如何解决rails中的“没有将类隐式转换为字符串”?
- amp-html - 将海报图片发送到 amp-youtube
- dart - 转换 dart http.get 请求以匹配构造函数
- git - 合并推送功能分支后,从主分支中删除功能分支的提交消息
- android - 如何在firestore中的数组索引下存储数据集合
- java - 如何在 Android 中意图动态生成 EditText 数据?
- swift - 如何等到firestore上的删除功能完成
- python - Gensim 包中的 Coherence 分数错误
- javascript - 函数内的 $scope 变量没有在 Angular js 中更新