You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历函数与Props映射的TypeScript类型匹配问题

解决TypeScript中组件与Props匹配的类型报错问题

我有一个存储React组件(对应component字段)及其对应Props(对应props字段)的映射对象,想要遍历该映射并调用component(props),但循环中TypeScript因类型范围过宽报错,示例代码及报错信息如下,如何让TypeScript识别同一对象的component与props是匹配的?

示例代码

const c1 = ({ }: { c1p1: number, c1p2: number }) => { }
const c2 = ({ }: { c2p1: number }) => { }
const c3 = ({ }: { c3p1: number }) => { }

const components = {
    c1: {
        component: c1,
        props: { c1p1: 11, c1p2: 12 }
    },
    c2: {
        component: c2,
        props: { c2p1: 21 }
    },
    c3: {
        component: c3,
        props: { c3p1: 31 }
    }
}

const selectedComponentNames: Array<keyof typeof components> = ["c1", "c2"]
selectedComponentNames.map(o => {
    const { component, props } = components[o]
    component(props)
})

报错信息(翻译后)

参数类型 '{ c1p1: number; c1p2: number; } | { c2p1: number; } | { c3p1: number; }' 无法赋值给类型 '{ c1p1: number; c1p2: number; } & { c2p1: number; } & { c3p1: number; }'。
类型 '{ c1p1: number; c1p2: number; }' 无法赋值给类型 '{ c1p1: number; c1p2: number; } & { c2p1: number; } & { c3p1: number; }'。
类型 '{ c1p1: number; c1p2: number; }' 中缺少属性 'c2p1',但类型 '{ c2p1: number; }' 中需要该属性。(2345)


解决方案

方法一:用泛型函数约束单个项的类型

创建泛型函数处理每个组件键值对,让TypeScript绑定具体键对应的精确类型:

const c1 = ({ }: { c1p1: number, c1p2: number }) => { }
const c2 = ({ }: { c2p1: number }) => { }
const c3 = ({ }: { c3p1: number }) => { }

const components = {
    c1: {
        component: c1,
        props: { c1p1: 11, c1p2: 12 }
    },
    c2: {
        component: c2,
        props: { c2p1: 21 }
    },
    c3: {
        component: c3,
        props: { c3p1: 31 }
    }
}

// 泛型函数明确当前键对应的组件与Props类型
const renderComponent = <K extends keyof typeof components>(key: K) => {
    const { component, props } = components[key];
    component(props);
};

const selectedComponentNames: Array<keyof typeof components> = ["c1", "c2"];
selectedComponentNames.map(renderComponent);

原理:泛型K会绑定到具体的键(比如"c1"),TypeScript能直接推断出该键下component和props的匹配类型,避免联合类型的冲突。

方法二:给映射对象添加精确类型定义

通过泛型接口强制每个组件项的component参数与props类型一致:

// 泛型接口约束组件和Props必须匹配
interface ComponentEntry<P> {
    component: (props: P) => void;
    props: P;
}

const c1 = ({ }: { c1p1: number, c1p2: number }) => { }
const c2 = ({ }: { c2p1: number }) => { }
const c3 = ({ }: { c3p1: number }) => { }

// 明确每个键对应的ComponentEntry类型
const components: {
    c1: ComponentEntry<{ c1p1: number, c1p2: number }>;
    c2: ComponentEntry<{ c2p1: number }>;
    c3: ComponentEntry<{ c3p1: number }>;
} = {
    c1: {
        component: c1,
        props: { c1p1: 11, c1p2: 12 }
    },
    c2: {
        component: c2,
        props: { c2p1: 21 }
    },
    c3: {
        component: c3,
        props: { c3p1: 31 }
    }
}

const selectedComponentNames: Array<keyof typeof components> = ["c1", "c2"];
selectedComponentNames.map(o => {
    const { component, props } = components[o];
    component(props);
});

原理:ComponentEntry<P>接口直接限制了每个组件项的component和props必须共享同一类型P,TypeScript能准确识别每个键对应的类型组合。


内容的提问来源于stack exchange,提问作者thesdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:11:09