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

为何TypeScript在普通函数与React组件中的表现存在差异?

React组件中Renders类型的Props参数提示失效问题

问题代码

type Block = { blockName: string }
type Parsers = Record<string, (block: Block) => object>
type Renders<T> = { [key in keyof T]: (props: ReturnType<T[key] extends Parsers[string] ? T[key] : never>) => string }

const Blocks = <P extends Parsers>(props: {
  parsers: P
  renders: Renders<P>
}) => {
  return null
}

这段代码在普通TypeScript环境下类型推断正常,但作为React组件调用时,renders中每个函数的props参数无法得到精确的类型提示,只能识别为object类型。

问题原因

核心问题在于Parsers类型使用了Record<string, (block: Block) => object>的宽泛索引签名。当泛型P约束为Parsers时,TypeScript会将P的所有属性统一推断为(block: Block) => object,丢失了每个parser函数具体的返回类型信息,导致Renders中的ReturnType无法提取精确的结构,最终props提示失效。

解决方案

修改泛型约束方式,让TypeScript保留每个parser函数的具体返回类型:

type Block = { blockName: string }
// 直接在泛型约束中定义parser结构,避免宽泛的Record索引签名
type Renders<T> = { [key in keyof T]: (props: ReturnType<T[key]>) => string }

const Blocks = <P extends { [K in keyof P]: (block: Block) => object }>(props: {
  parsers: P
  renders: Renders<P>
}) => {
  return null
}

验证示例

调用组件时,renders中的props会自动获得精确的类型提示:

Blocks({
  parsers: {
    text: (block) => ({ content: block.blockName, size: 16 }),
    image: (block) => ({ src: 'test.jpg', alt: block.blockName })
  },
  renders: {
    text: (props) => {
      // 正确提示props.content(string类型)和props.size(number类型)
      return `<div style="font-size: ${props.size}px">${props.content}</div>`
    },
    image: (props) => {
      // 正确提示props.src和props.alt(均为string类型)
      return `<img src="${props.src}" alt="${props.alt}" />`
    }
  }
})

备选方案(保留Parsers类型)

如果需要保留Parsers类型定义,可以将其改为泛型形式,避免固定的索引签名:

type Block = { blockName: string }
type Parsers<T extends string> = { [K in T]: (block: Block) => object }
type Renders<T> = { [key in keyof T]: (props: ReturnType<T[key]>) => string }

const Blocks = <T extends string, P extends Parsers<T>>(props: {
  parsers: P
  renders: Renders<P>
}) => {
  return null
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:27:21