为何TypeScript不校验传入Props的函数返回对象内容?
TypeScript不对返回对象不符合类型的函数Prop做校验的原因与解决办法
问题现象
你定义的TableProps中,rowProps既接受RowPropsWithoutSx对象,也接受返回该类型的函数。但使用时出现差异:
- 直接传包含额外属性(如
sx)的对象时,TypeScript会正确报错; - 传返回包含额外属性对象的函数时,TypeScript不会识别错误,无报错提示。
核心原因
这是TypeScript的默认类型推断行为导致的:
当你直接写对象字面量赋值给rowProps时,TS会立刻将它与目标类型RowPropsWithoutSx做严格匹配,检测到额外属性就会报错。但对于函数返回的对象字面量,TS默认采用「宽化推断」——它会把这个对象推断成一个包含所有声明属性的宽泛类型(允许额外属性),而不会主动去匹配RowPropsWithoutSx的约束,除非你显式指定了函数的返回类型。
这种设计是为了在无明确类型约束时,给开发者更多灵活性,但也导致了这种场景下的校验缺失。
解决办法
1. 显式指定函数返回类型
这是最直接的方式,明确告诉TS函数必须返回RowPropsWithoutSx类型:
<Table rowProps={(row): RowPropsWithoutSx => ({ _focusWithin: undefined, sx: '', // 此处TS会正确报错,提示sx不存在于RowPropsWithoutSx中 })} />
2. 使用类型断言强制约束返回值
通过as关键字强制将返回对象断言为目标类型,触发TS的严格校验:
<Table rowProps={() => ({ _focusWithin: undefined, sx: '', } as RowPropsWithoutSx)} // 此处TS会报错,因为sx不属于目标类型 />
3. 优化Prop类型定义(强化约束)
可以将函数类型单独抽离,让TS在类型层面更明确地约束返回值:
// 单独定义严格的函数类型 type RowPropsCallback<T> = (row?: TableData<T>) => RowPropsWithoutSx; export type TableProps<T> = { rowProps?: RowPropsWithoutSx | RowPropsCallback<T>; // ... 其他Props };
这种方式能让TS更清晰地识别函数的返回值要求,配合类型推断减少漏检。
内容的提问来源于stack exchange,提问作者ddblair
相关产品推荐
相关产品推荐

