如何为使用exact()定义的类型分配对象变量?
- 定义了如下PropTypes类型:
export const MyType = PropTypes.exact({ id: PropTypes.number.isRequired, name: PropTypes.string.isRequired })
- 存在一个接收对应类型参数的函数:
public function doSomething(x: InferProps<typeof MyType>) { // 执行相关操作 }
- 当用以下对象调用该函数时:
const y = { id: 1, name: "y", }
触发了TypeScript错误:
Argument of type { id: number; name: string; } is not assignable to parameter of type
InferProps<Requireable<Required<InferProps<{ id: Validator; name: Validator ; }>>>>
Property isRequired is missing in type { id: number; name: string; } but required in type
InferPropsInner<Pick<Requireable<Required<InferProps<{ id: Validator; name: Validator ; }>>>, "isRequired">>
这个错误的核心原因是PropTypes.exact()返回的类型结构,导致InferProps无法正确推断出目标属性类型,反而误将PropTypes自身的结构当成了参数要求。
有两种实用的解决方式:
方式一:直接定义TypeScript接口(推荐)
既然已经使用TypeScript,直接定义对应的TS接口比依赖PropTypes的类型推断更可靠:
// 定义TS接口 interface MyType { id: number; name: string; } // 函数参数直接使用该接口 public function doSomething(x: MyType) { // 执行相关操作 }
此时y的类型会自动匹配接口,不会再出现类型不兼容的错误。
方式二:拆分PropTypes定义以修正推断
如果必须保留PropTypes的定义,可以拆分结构,让InferProps正确解析属性类型:
// 先定义内部的属性校验规则 const MyTypeRules = { id: PropTypes.number.isRequired, name: PropTypes.string.isRequired }; // 再用exact包裹导出 export const MyType = PropTypes.exact(MyTypeRules); // 函数参数使用InferProps解析原始规则的类型 public function doSomething(x: InferProps<typeof MyTypeRules>) { // 执行相关操作 }
这样InferProps会正确识别MyTypeRules的结构,推断出与y匹配的{ id: number; name: string; }类型。
内容的提问来源于stack exchange,提问作者user7167081

