TypeScript未正确校验map()函数返回对象的类型问题
TypeScript未正确校验map()函数返回对象的类型问题
嘿,我来帮你捋清楚这个TypeScript类型校验的问题哈!你这段代码里的问题其实挺典型的,咱们先看你写的代码:
type Item = { selection: ItemSelection; }; type ItemSelection = { selected: number; result?: Result; }; type Result = { success: boolean; }; const data: string[]=[]; const items: Item[] = data.map((item) => ({ selection: { selected: 0, success: true, }, }));
你肯定已经发现了,这段代码里的map回调返回的对象其实不符合Item类型的定义对吧?按照你声明的类型,selection是ItemSelection类型,它的success属性应该嵌套在可选的result对象里,而不是直接挂在selection上。那为啥TypeScript没给你报错呢?
这其实是TypeScript结构类型兼容性的特性在搞事情:当对象作为函数返回值(比如map回调的返回结果),而不是直接作为字面量赋值给变量时,TypeScript的「额外属性检查」会放宽要求——只要对象包含目标类型的所有必填属性,它就会认为类型兼容,哪怕多了额外的属性。但这显然和你定义的类型结构逻辑不符,属于代码里的逻辑错误。
那怎么修正这个问题,同时让TypeScript能严格校验出来呢?
- 首先是修正代码结构,把
success放到正确的嵌套层级里,这才是符合你类型定义的写法:
const items: Item[] = data.map((item) => ({ selection: { selected: 0, result: { success: true, }, }, }));
- 如果想让TypeScript严格禁止这种额外属性的情况,你可以把
ItemSelection定义成精确类型,通过交叉Record<string, never>来限制它不能有额外属性:
type ItemSelection = { selected: number; result?: Result; } & Record<string, never>;
这样一来,如果你再把success直接放到selection里,TypeScript就会立刻抛出类型错误,帮你提前发现问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

