好的,所以我正在升级wj-config的 TypeScript (以防实际情况变得相关),它的一个功能是将键(根据分隔符的存在而拆分的字符串值)“扩展”为对象。示例:键'a.b.c'
扩展为对象{ a: b { c: <value here> } }
。
对于单个键,我创建了以下InflateKey
类型:
export type InflateKey<TKey extends string, TValue, TSep extends string> = TKey extends `${infer Key}${TSep}${infer Rest}` ?
{
[K in Key]: InflateKey<Rest, TValue, TSep>
} :
{
[K in TKey]: TValue;
};
此类型按预期工作。太棒了!现在下一个任务是接受一个对象,其键与上面描述的键类似。示例:
const dic = {
'a.b': 1,
'a.c': 33,
'h.x': true,
'z.y': 'Hi'
};
// Now, through the application of a function, the result will look like:
const result = {
a: {
b: 1,
c: 33
},
h: {
x: true
},
z: {
y: 'Hi'
}
};
我需要帮助输入这个返回值。
我的思路是:
export type InflateDictionary<TDic extends Record<string, any>> = InflateKey<key1 of TDic,...> & ... & InflateKey<keyN of TDic,...>;
当然,以上内容不是有效的 TypeScript。
你已经写过
InflateKey<K, V, ".">
(我假设我们只关心"."
这里)并且想要看起来像中所有属性的交集,对吗?如果是这样,那么我们可以使用与将并集类型转换为交集类型中相同的基本方法。InflateKey<K, T[K], ".">
K
keyof T
我们的想法是,我们生成一个类型,其中每个类型
InflateKey<K, T[K], ".">
最终都处于逆变位置(请参阅TypeScript 中方差、协方差、逆变、双方差和不变性之间的区别),例如函数的参数。然后我们使用条件类型推断来推断该位置的单一类型。从逆变位置的多个候选者进行条件类型推断会产生一个交集(请参阅TypeScript 2.8 发行说明中的文档)。因此,这里有一种方法可以做到这一点:我们对 的所有-keyed 属性创建一个映射类型(而不是仅仅因为需要一个键),并将每个属性作为属性的函数参数。然后我们推断,为整个对象推断一个。这将是您想要的交集,所以我们返回它。
string
TDic
string & keyof TDic
keyof TDic
InflateKey
string
InflateKey
Record<string, (x: infer I) => void>
I
I
让我们测试一下:
看起来不错。这就是你想要的类型。
游乐场链接到代码