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

TypeScript+React中如何基于父组件props推导子组件value合法取值

实现方案

可以实现该需求,核心思路是通过泛型工厂函数将父子组件的类型绑定在同一个作用域下,无需每个子组件手动声明泛型,同时保证父子组件的上下文类型强关联。

核心实现

import React, { createContext, useContext } from 'react';

// 泛型工厂函数,传入你需要的上下文类型即可生成对应的父子组件对
function createParentChildPair<T>() {
  // 内部创建仅当前组件对可用的Context,泛型直接绑定传入的T
  const Context = createContext<T | null>(null);

  // Parent组件的context参数自动限制为T类型
  const Parent = ({ context, children }: { context: T; children: React.ReactNode }) => {
    return <Context.Provider value={context}>{children}</Context.Provider>;
  };

  // Child组件的value参数自动推导为keyof T,无需用户额外指定泛型
  const Child = ({ value }: { value: keyof T }) => {
    const ctx = useContext(Context);
    if (!ctx) throw new Error('Child 组件必须嵌套在对应 Parent 组件内部使用');
    // 此处可自行补充业务渲染逻辑
    return <>{ctx[value] as React.ReactNode}</>;
  };

  return { Parent, Child };
}

使用示例

interface IMyComplexObject {
    name: string;
    surname: string;
}

// 仅需此处声明一次泛型,生成的Parent和Child自动绑定该类型
const { Parent, Child } = createParentChildPair<IMyComplexObject>();

const MyApp = (props) => {
    const [obj, setObj] = React.useState<IMyComplexObject>({name: 'Foo', surname: 'Bar'});

    return (
        <Parent context={obj}>
            {/* 输入value时会自动提示可选值为 'name' | 'surname',输入不存在的键直接报类型错误 */}
            <Child value={'name'} />
            <Child value={'surname'} />
        </Parent>
    );
}

方案优势

  • 无冗余代码:所有子组件的泛型在工厂生成阶段一次性绑定,不需要每个Child单独声明泛型
  • 类型强安全:父子组件的上下文类型完全关联,不可能出现父组件传A类型、子组件用B类型仍通过校验的问题
  • 复用性强:不同业务场景只需调用多次工厂函数生成独立的组件对即可,互相不影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:39:03