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

如何让React组件的泛型参数成为必填项?

如何让React组件的泛型参数成为必填项

问题描述

想要让React组件的泛型参数必须显式指定,要是在JSX里省略了泛型参数(比如写<ChildComponent/>而不是<ChildComponent<Employee/>),TypeScript得直接报类型错误,提示类似“Expected 1 type argument, but got 0.”的信息。

给出的代码示例:

interface Common {
    id: string;
}

interface ChildComponentProps<T> {
    renderFun: (item: T) => React.ReactNode;
}

const ChildComponent = <T extends Common, >(props: ChildComponentProps<T>) => {
    return <></>;
};

interface Employee extends Common {
    name: string;
    position: string;
    department: string;
}

const ParentComponent = () => {
    return (
        <>
            <ChildComponent<Employee>
                renderFun={(item) => <>{item.department}</>}
            />
        </>
    );
};

interface Device extends Common {
    model: string;
}

const OtherParentComponent = () => {
    return (
        <>
            <ChildComponent<Device>
                renderFun={(item) => <>{item.model}</>}
            />
        </>
    );
};

解决方案

要强制泛型必须显传,核心就是不让TypeScript从组件props里自动推断泛型类型,断了它通过renderFun参数反向推导T的路,这样就只能由开发者手动指定泛型。

方法1:用NoInfer类型打破自动推断

先整个NoInfer工具类型,专门用来阻止TS自动推断泛型:

// 用来阻止TypeScript自动推断泛型的工具类型
type NoInfer<T> = [T][T extends any ? 0 : never];

interface Common {
    id: string;
}

interface ChildComponentProps<T> {
    // 把item的类型改成NoInfer<T>,让TS没法从renderFun里推断出T
    renderFun: (item: NoInfer<T>) => React.ReactNode;
}

// 泛型参数不设默认值,强制必须显式传入
const ChildComponent = <T extends Common>(props: ChildComponentProps<T>) => {
    return <></>;
};

这时候要是你省略了泛型参数(比如写<ChildComponent renderFun={(item) => ...} />),TS会直接报错:Expected 1 type argument, but got 0.,完全符合要求。

方法2:给泛型设默认值为never

还有个更简单的办法,给泛型参数设个默认类型never,这样不传泛型的时候,T就变成never,renderFun的参数类型也是never,你在里面用item的属性时就会报错:

interface Common {
    id: string;
}

interface ChildComponentProps<T> {
    renderFun: (item: T) => React.ReactNode;
}

// 给泛型设默认值为never
const ChildComponent = <T extends Common = never>(props: ChildComponentProps<T>) => {
    return <></>;
};

这种方式下,省略泛型会触发类似Property 'department' does not exist on type 'never'.的错误,虽然不是直接提示缺泛型,但同样能逼着你必须显传泛型参数。

说明

方法1的好处是报错提示更精准,直接说缺泛型参数;方法2写起来更省事,适合快速实现。根据自己的需求选就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:35:16