我想创建一个Typescript帮助器类型来提高类型安全性。我想让Typescript将对象键作为文本来“计算”和检查。
目前我有Word
和Card
类型,但是Word
类型中的字段很难看,没有真正进行类型检查。
type Card = {
word_1: Word
word_2: Word
}
type Word = {
// ... other stuff
in_Cards_as_word_1: Card[]
in_Cards_as_word_2: Card[]
}
编辑:使用@jcalz的LiteralOf
实现:
interface TypeMap {
Card: Card;
Date: Date;
}
type LiteralOf<T> = { [K in keyof TypeMap]: T extends TypeMap[K] ? K : never }[keyof TypeMap];
是否可以像下面这样使用类型检查过的helper InAs
?
type InAs<T extends LiteralOf<T>, F extends keyof T> = `in_${LiteralOf<T>}_as_${F}`
type Word = {
// ... other stuff
InAs<Card, 'word_1'>: Card[]
InAs<Card, 'word_2'>: Card[]
}
const word: Word
// this should be valid, because `InAs` uses `LiteralOf` and
// something like a literal interpolation under the hood
word.in_Card_as_word_1
1条答案
按热度按时间jckbn6z71#
最后一种通用方法是假设对于给定的类型
T
,我们总是要迭代它的所有属性,并且属性类型将是T[]
:这里
InAsT<T>
使用Map类型中的键重Map将每个键K
从T
的键转换为InAs<T, K>
。更一般的做法是允许将属性值类型指定为
V
,而不是假定为T[]
:我能想到的最通用的解决方案是允许输出的每个属性被单独指定,这并没有一个 * great * 语法;每个属性都需要一个三元组类型
T
,它的键之一K
,以及结果属性的预期值类型V
,所以也许它应该取元组类型的并集,如下所示:这基本上是相同的操作,只是我们不是迭代
T
的每个键,而是迭代TKV
的每个联合成员,在作为键值输出之前,我们将其拆分为T
、K
和V
。我还做了一个约束
C
,以确保对于TKV
的每个成员,K
元素都是T
元素的键,它(ab)使用一个泛型类型参数default来做这件事,以避免循环警告(否则TKV
以编译器不喜欢的方式直接依赖于它自己)。无论如何,这取决于您的用例,您希望采用其中的一种方法(或这些方法的组合)。
Playground代码链接