开启exactOptionalPropertyTypes时,如何正确定义TypeScript对象映射?
解决开启
exactOptionalPropertyTypes: true时对象映射的类型问题 当开启exactOptionalPropertyTypes: true后,使用对象作为映射会遇到两个不符合预期的问题:
- 允许为属性赋值
undefined,但我们希望禁止这种操作 Object.values()返回的类型包含undefined,无法直接赋值给纯净的User[]
问题示例
type User = {name: string} const userMap: {[key in string]?: User} = {} userMap.a = {name: 'Elise'} userMap.b = {name: 'Eve'} userMap.a = undefined // 当前允许,但我们希望此处报错 const users: User[] = Object.values(userMap) // 报错:Type 'User | undefined' is not assignable to type 'User'
解决方案
去掉索引签名中的可选标记?,使用普通的索引签名类型(或等价的Record<string, User>):
type User = {name: string} // 两种写法等价,选其一即可 const userMap: {[key: string]: User} = {} // 或 const userMap: Record<string, User> = {} userMap.a = {name: 'Elise'} userMap.b = {name: 'Eve'} userMap.a = undefined // 此处会报错:Type 'undefined' is not assignable to type 'User' const users: User[] = Object.values(userMap) // 类型匹配,无报错
原理说明
- 当开启
exactOptionalPropertyTypes: true时,{[key in string]?: User}表示属性可以是User、undefined,或者不存在。去掉?后,类型变为所有存在的属性必须是User类型,不允许赋值undefined。 - 普通索引签名类型下,
Object.values()会返回User[],因为TypeScript推断所有存在的属性值都是User,不会包含undefined。
内容的提问来源于stack exchange,提问作者user19206179
相关产品推荐
相关产品推荐

