TypeScript中Exclude处理推断类型返回never的问题解决方法
问题描述
我希望通过函数预配置组件的部分props,使该函数返回的组件不再需要传入已预配置的props。示例代码如下:
function createExtendedComp<Props>(Comp: (props: Props) => any) { const ExtendendComp = (props: Props) => { return Comp(props) } ExtendendComp.attrs = <Result extends Partial<Props>>(attrs: Result) => { const PreconfiguratedComp = (props: Exclude<Props, Result>) => { return Comp({...props, ...attrs}) } return PreconfiguratedComp } return ExtendendComp } function Comp (props: { test: string, style: string }) { return props } const PreconfigComp = createExtendedComp(Comp).attrs({ test: 'ok' }) PreconfigComp({ style: 'test' }) // <- Argument of type '{ style: string; }' is not assignable to parameter of type 'never'.
当前类型推断存在问题:TypeScript认为PreconfigComp的参数类型是never,但我预期应为{ style: string }。请问如何从Props中移除已在Result中处理的部分?
解决方案
问题出在Exclude<Props, Result>的使用上——Exclude是专门处理联合类型的排除逻辑,而这里的Props和Result都是对象类型,所以不能直接用它剔除对象属性。
要实现从Props中移除Result包含的属性,需要结合Omit和keyof来精准操作对象的键:
优化后的代码如下:
function createExtendedComp<Props>(Comp: (props: Props) => any) { const ExtendendComp = (props: Props) => { return Comp(props) } // 用键泛型K明确预配置的是Props的子集键 ExtendendComp.attrs = <K extends keyof Props>(attrs: Pick<Props, K>) => { // 用Omit移除Props中属于K的所有属性 const PreconfiguratedComp = (props: Omit<Props, K>) => { return Comp({...props, ...attrs}) } return PreconfiguratedComp } return ExtendendComp } function Comp (props: { test: string, style: string }) { return props } const PreconfigComp = createExtendedComp(Comp).attrs({ test: 'ok' }) PreconfigComp({ style: 'test' }) // 类型正确,参数类型为{ style: string }
关键说明:
K extends keyof Props:明确预配置的属性键是Props的子集,让TypeScript能精准推断出具体的键名(比如这里的"test")。Pick<Props, K>:约束attrs的类型必须是Props中K键对应的属性结构,避免传入非法属性。Omit<Props, K>:直接从Props中移除K对应的所有属性,得到剩余需要传入的props类型,完全符合预期。
内容的提问来源于stack exchange,提问作者Sharcoux
相关产品推荐
相关产品推荐

