TypeScript中keyof直接使用与作为泛型约束的行为差异疑问
TypeScript中keyof联合类型与泛型keyof的行为差异原因
核心差异是两种写法中key的类型确定性不同,TypeScript对联合类型和泛型参数的类型推导逻辑有明显区别:
直接使用keyof Data报错的原因
keyof Data本质是一个联合类型:"someKey1" | "someKey2" | "someKey3",当你直接将key声明为该联合类型时,TS只会识别到key是三个可能的字面量之一,不会关联「同一个key对应的取值位置和赋值位置的类型必须匹配」的逻辑:
- 右侧
data[key]的类型推导结果是Data[keyof Data],即string | number | boolean的联合类型 - 左侧
dataCopy[key]的类型是Partial<Data>[keyof Data],由于TS在处理「未知具体键的联合类型赋值」时,要求赋值内容必须满足所有可能键对应类型的交集,string、number、boolean三个类型没有公共交集,最终推导为never类型,因此会抛出联合类型不能赋值给never的错误。
泛型写法校验通过的原因
使用<K extends keyof Data>声明泛型参数时,K是一个绑定到当前调用上下文的具体类型参数:
每次forEach回调执行时,K都会被缩小为当前遍历到的键对应的具体字面量类型(比如某次遍历K的实际类型为"someKey1"),此时TS可以明确:
- 右侧
data[K]的类型是Data[K](比如对应string) - 左侧
dataCopy[K]的类型是Partial<Data>[K],也就是Data[K] | undefined
二者类型完全匹配,因此可以正常通过校验。
补充提示:TypeScript默认
Object.keys返回string[]是有意设计的,因为TS的类型是结构化的,无法保证运行时对象不存在接口声明外的额外属性,直接将key强转为keyof Data属于类型断言,需要自行保证安全性。
内容的提问来源于stack exchange,提问作者Tonnio
相关产品推荐
相关产品推荐

