英文:
How to make a Record with union type as key not mandatory for all values?
问题
在一个TypeScript项目中,我有一个类型中的一个封闭字符串属性:
type SubscriptionLevel = 'normal' | 'premium' | 'cancelled';
我想创建一个类似于映射的对象,使用这个类型作为键,但不是所有值都是必需的。
一个非常简单的例子是这样的:
const badgeIcon: Record<SubscriptionLevel, string | undefined> = {
'premium': 'crown',
'cancelled': 'grayed',
}
我只想为某些值指定映射值(这里我得到字符串,但实际代码将导致以不同方式渲染React组件)。
这段代码在运行时运行,但TypeScript会抱怨:“属性 'normal' 在类型 '{ premium: string; cancelled: string; }' 中丢失,但在类型 'Record<SubscriptionLevel, string | undefined>' 中是必需的。(2741)”。
我可以通过添加 'normal' 键来修复代码:
const badgeIcon: Record<SubscriptionLevel, string | undefined> = {
'premium': 'crown',
'cancelled': 'grayed',
'normal': undefined
}
但这种方法需要是穷尽的,即使只有少数键需要有值(我的实际代码有10个键,但只有2个必须设置)。
所以我的问题是:有没有一种简单的方法来创建这个映射,其中的值是可选的?
类型安全很重要,所以我不想使用 'string' 作为键,因为它不会检查拼写错误。
英文:
In a typescript project, I have a closed string property in a type:
type SubscriptionLevel = 'normal' | 'premium' | 'cancelled';
I want to create a map-like object that use this type as a key, but not mandatory for all values.
A very simple example is this:
const badgeIcon : Record<SubscriptionLevel, string | undefined> = {
'premium' : 'crown',
'cancelled' : 'grayed',
}
I want, only for some of the values, to specify mapped values (here I get string but actual code will lead to rendering react component differently).
This code run at runtime but Typescript complains that Property 'normal' is missing in type '{ premium: string; cancelled: string; }' but required in type 'Record<SubscriptionLevel, string | undefined>'.(2741)
.
I can fix the code by adding also the normal
key:
const badgeIcon : Record<SubscriptionLevel, string | undefined> = {
'premium' : 'crown',
'cancelled' : 'grayed',
'normal': undefined
}
But this approach requires to be exhaustive, even if only few kays should have a values (my actual code has 10 keys, but only 2 have to be set).
So my question is: is there any simple way to create this map, with optional values?
Type safety is important, so I don't want to use 'string' as key, because it won't check for typos.
答案1
得分: 2
你正在寻找内置的实用类型 Partial:
type SubscriptionLevel = 'normal' | 'premium' | 'cancelled';
const badgeIcon: Partial<Record<SubscriptionLevel, string | undefined>> = {
premium: 'crown',
cancelled: 'grayed',
};
英文:
You are looking for built-in utility type Partial:
type SubscriptionLevel = 'normal' | 'premium' | 'cancelled';
const badgeIcon: Partial<Record<SubscriptionLevel, string | undefined>> = {
premium: 'crown',
cancelled: 'grayed',
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论