我想创建一个对象,其中键以文字类型定义,而值是通过函数运行每个键的结果。这个想法是拥有一个由文字类型中的条目定义的对象。我还希望能够为特定键添加不同的值,这些键不应该通过其余键运行的函数来运行。
这是我正在尝试做的一个示例:
function capitalizeString(string: string) {
return string[0].toUpperCase() + string.substring(1)
}
type fruits = "apple" | "orange" | "pineapple" | "pear" | "orange" | "melon"
const fruitObject:{ [key in fruits]: string} = {
// Would create key/value pairs of all of the entries in the literal type
[key]: capitalizeString(key),
// custom values that aren't being handled by the function
orange: "oRaNgE",
melon: "meloN",
}
这是一个简单的示例,我知道有更好的方法来解决这个特定问题,但我更感兴趣的是是否可以做到这一点,而不是如何改进这个特定的示例。
在你的
fruitObject
定义中,你试图执行某种理解,这在 TypeScript 中是不可能的。不过,您的问题仍然有解决方案。
首先,我们不能循环联合类型,因为它们存在于类型域中。相反,我们可以创建一个包含键的
readonly
列表并提取其类型。这样我们就可以有效地循环联合类型。
const fruits = ["apple", "orange", "pineapple", "pear", "orange", "melon"] as const;
type Fruits = (typeof fruits)[number];
type FruitObject = {[Key in Fruits]: string}
Fruits
现在将是 "apple"
、"orange"
、"pineapple"
等的联合类型,与原始 fruits
类型相同。通过这种方法,我们可以编辑数组以包含更多水果,所有内容都会相应更新。
接下来,我们需要创建一个函数来接受水果列表并将该数组简化为一个对象:
function fruitObjectFactory(fruitArray: readonly Fruits[]): FruitObject {
return fruitArray.reduce((acc, key) => {
acc[key] = capitalizeString(key);
return acc;
}, {} as FruitObject);
}
这可以使用数组
.reduce()
方法来完成,其中累加器的类型为 FruitObject
。
最后,我们可以在对象定义中调用此函数,并使用展开运算符 (
...
),我们可以组合两个对象。
const fruitObject: FruitObject = {
...fruitObjectFactory(fruits),
orange: "oRaNgE",
melon: "meloN",
}
您会注意到
...fruitObjectFactory(fruits)
将创建一个对象,其中包含 fruits
数组中的所有字符串,但您想要例外。 orange: "oRaNgE"
和melon: "meloN"
的定义分别覆盖orange: "Orange"
和melon: "Melon"
键值对。
注意,
readonly
回调方法中的.reduce()
不是必需的。我添加它只是为了传递原始 fruits
数组,由于 readonly
运算符,该数组的类型为 as const
。