首先,我们给出下面👇🏻这段代码,`fruitCount`的每个属性值类型都是`number`,我们期望由它衍生出一个`singleFruitCount`对象
export const fruitCount = {apple: 1,
pear: 4,
banana: 26,
}
/**
**/
type SingleFruitCount
=
any//怎么定义❓
const singleFruitCount:
SingleFruitCount
= {
banana: 12,
}
你可能会想到以下两个方案
//
方案1
type SingleFruitCount = {
[k in keyof typeof fruitCount]?:number
}
//
方案2
type SingleFruitCount =
| {
apple: number;
}
| {
banana: number;
}
| {
pear: number;
}
_方案1_看起来更简洁并且可以满足我们的需要,但是他是一个`partial`并不是一个`union`类型,`union`跟`partial`相比有更多的转换能力,我们会在下一个`tips`中体现。
让我们回到_方案2_,_方案2_虽然能满足需求,但是看起来并不那么优雅,所以让我们改进一下,先从`fruitCounts`对象中创建一个`FruitCount`类型,然后我将衍生出一个新的类型`NewSingleFruitCount`
type FruitCounts = typeof fruitCounts
type NewSingleFruitCount = {
[K in keyof FruitCounts]: {}
}
/**
它将 FruitCounts 的每个属性值设置为一个空对象
因此,当我们使用它时,TypeScript将期待一个像这样的效果👇🏻
**/
const singleFruitCount: NewSingleFruitCount = {apple: {},
pear: {},
banana: {}
}
但是我们期望属性值的类型是`number`,我们进行下一步改进
type NewSingleFruitCount = {
[K in keyof FruitCounts]: {
[K2 in K]: number
}
}
//效果如下👇🏻
const singleFruitCount: NewSingleFruitCount = {apple: {
apple: 2,
},
pear: {
pear: 4,
},
banana: {
banana: 26,
},
}
最后,我们通过映射`NewSingleFruitCount`类型,来获取真实的值
type NewSingleFruitCount = {
[K in keyof FruitCounts]: {
[K2 in K]: number
}
}[keyof FruitCounts]
这样就可以获取到真实的结果🎉
const singleFruitCount: NewSingleFruitCount = {apple: 2,
}
const singleFruitCount:SingleFruitCount = {}//期望 ts 能够报错,但是它并不会报错type SingleFruitCount = {
[k in keyof typeof fruitCount]?:number
}
