为何Partial<Record<string, string>>不extends Record<string, string>,而Partial<{id:string}>可以?
TypeScript中Partial与Record<string, string>的条件类型匹配问题
先看这段代码:
type Check<T> = T extends Record<string, string> ? true : false type T1 = Check<{ id: string }> // true type T2 = Check<Partial<{ id: string }>> // true type T3 = Check<Record<string, string>> // true type T4 = Check<Partial<Record<string, string>>> // false
核心疑惑点:同样是Partial包装的类型,为什么Partial<{ id: string }>能通过Check判断为true,而Partial<Record<string, string>>却返回false?
原因其实是具体对象类型和索引签名类型在TypeScript结构兼容性检查中的规则差异:
Partial<{ id: string }>是带有可选属性的具体对象类型,等价于{ id?: string }。TypeScript判断它是否extendsRecord<string, string>时,会把可选属性的undefined解读为「该属性可能不存在」,而非「属性值允许是undefined」。只要这个类型中存在的属性(如果有的话)的类型符合Record<string, string>的要求(这里id存在时类型是string),就会判定为兼容,所以返回true。Partial<Record<string, string>>是带有可选索引签名的类型,等价于{ [key: string]: string | undefined }。这是一个索引签名类型,明确规定所有字符串键对应的属性可以是string或undefined。而Record<string, string>要求所有字符串键的属性必须是string,string | undefined并不是string的子类型,因此整个类型不兼容,返回false。
内容的提问来源于stack exchange,提问作者Jin
相关产品推荐
相关产品推荐

