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

React渲染Prop函数的TypeScript类型报错及解决方案

处理React渲染Prop/函数的工具函数优化方案

我之前编写了一个用于渲染可能为React渲染Prop/函数的属性的函数,初始实现如下:

import { isValidElement } from 'react';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AnyFunction = (...args: any) => any;

export function isRenderFunction<F extends AnyFunction>(
  subject: React.ReactNode | F
): subject is F {
  return !isValidElement(subject) && subject instanceof Function;
}

export function render<F extends AnyFunction>(
  subject: React.ReactNode | F,
  ...parameters: Parameters<F>
): React.ReactNode {
  return isRenderFunction(subject) ? subject(
    // @ts-ignore
    ...parameters
  ) : subject ?? null;
}

这个函数运行逻辑没问题,但有个类型痛点:移除// @ts-ignore注释后,TypeScript会抛出错误:Type 'Parameters' must have a 'Symbol.iterator' method that returns an iterator.ts(2488)。如果尝试把参数类型改成Parameters<F>[],所有调用render函数的地方又都会报错。

后来我通过提炼几个辅助类型,得到了一份在代码逻辑和类型检查上都表现良好的最终实现:

import { ReactNode, isValidElement } from 'react';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AnyArg = any;

export type RenderFunction<A extends AnyArg[]> = (...args: A) => ReactNode;
export type RenderProp<A extends AnyArg[]> = ReactNode | RenderFunction<A>;

export function isRenderFunction<A extends AnyArg[]>(
  subject: RenderProp<A>
): subject is RenderFunction<A> {
  return !isValidElement(subject) && subject instanceof Function;
}

export function render<A extends AnyArg[]>(
  subject: RenderProp<A>,
  ...parameters: A
): ReactNode {
  return isRenderFunction(subject) ? subject(...parameters) : subject ?? null;
}

这里的核心优化是通过RenderFunction和RenderProp这两个自定义类型,明确了渲染函数和渲染属性的类型约束,既解决了之前的类型报错问题,也让代码的可读性和类型安全性更上一层楼。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:27:39