React Context Provider中如何基于propProvide的keyof定义propData类型?
解决方案
1. 定义带泛型的Provider与Context
通过泛型捕获propProvide的结构,让Context能携带该结构的类型信息:
import { createContext, useContext, ReactNode } from 'react'; // Provider的props类型,泛型T约束propProvide的结构 type MyComponentProviderProps<T extends Record<string, unknown>> = { propProvide: T; children: ReactNode; }; // 创建泛型Context,初始值设为null const MyComponentContext = createContext<Record<string, unknown> | null>(null); // 实现Provider组件,用泛型T保留propProvide的类型信息 function MyComponentProvider<T extends Record<string, unknown>>({ propProvide, children, }: MyComponentProviderProps<T>) { return ( <MyComponentContext.Provider value={propProvide}> {children} </MyComponentContext.Provider> ); }
2. 定义空格分隔的Key类型工具
创建递归类型,确保propData只能是propProvide的key以空格分隔的组合:
// 生成允许空格分隔的key组合类型 type SpaceSeparatedKeys<T extends string> = T | `${T} ${SpaceSeparatedKeys<T>}`;
3. 实现类型约束的ComponentChild
让子组件关联Context的类型,同时限制propData为合法的空格分隔key:
// 子组件props类型,泛型T关联Provider中propProvide的结构 type ComponentChildProps<T extends Record<string, unknown>> = { propData: SpaceSeparatedKeys<keyof T & string>; }; function ComponentChild<T extends Record<string, unknown>>({ propData, }: ComponentChildProps<T>) { // 断言Context值为T类型(确保在Provider内部使用) const contextData = useContext(MyComponentContext) as T; // 分割propData获取对应值示例 const targetValues = propData.split(' ').map(key => contextData[key]); return <div>{targetValues.join(', ')}</div>; }
4. 使用示例
此时TypeScript会自动校验propData的合法性,传入不存在的key会直接报错:
<MyComponentProvider propProvide={{ dataA: "10", dataB: "20" }} > {/* 合法:仅允许propProvide的key以空格分隔 */} <ComponentChild propData="dataA dataB" /> {/* 非法:TypeScript会提示类型错误 */} {/* <ComponentChild propData="dataC" /> */} </MyComponentProvider>
内容的提问来源于stack exchange,提问作者Hai Tien
相关产品推荐
相关产品推荐

