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

如何调整JSX/TS对组件属性的处理以适配自定义框架?

自定义伪JSX框架的TypeScript类型兼容问题

我正在开发一款采用伪JSX语法的框架,通过reactive、props、for这类特殊属性提供指令,示例代码如下:

interface User {
  name: string;
}

const UserDetails = (user: User) => <div>Hi {user.name}</div>;

const UserList = (manager: User, users: User[]) => (
  <div reactive>
    <UserDetails props={manager} as:manager/>
    <UserDetails for={users} as:list/>
  </div>
);

该框架的JSX会被Babel插件剥离,不需要执行,功能已经正常运行,但TypeScript一直抛出类似React场景下的类型警告:

error TS2322: Type '{ props: User; "as:manager": true; }' is not assignable to type 'IntrinsicAttributes & User'.
  Property 'props' does not exist on type 'IntrinsicAttributes & User'.

    <UserDetails props={manager} as:manager />

注意:这是我框架中JSX的预期用法,不要提供React风格的属性传递方案。

核心需求

  • 阻止TypeScript将<UserDetails />这类大写开头的元素视为对对应函数的调用,避免类型警告
  • 确保TypeScript能检测到UserDetails被引用,不会标记它为模块中未使用的变量

进阶期望是能让TS/JSX把大写元素映射到一个中间函数:要么接受任意参数消除警告,要么更好地复用原组件函数的签名——允许props参数匹配原组件的参数类型,for参数匹配原组件参数的数组类型。

已尝试的方案

  • 调整JSX命名空间的类型定义,试过多种变体但无效:
declare namespace JSX {
  // Empty interface to represent JSX.Element
  interface Element {
  } 

  interface ElementClass {
    [elemName: string]: any;
  }

  interface IntrinsicElements {
    [elemName: string]: any;
  }

  interface IntrinsicAttributes {
    [elemName: string]: any;
  }
}
  • 尝试引入虚拟JSX工厂函数:
export const jsx = (tag: any, props: any, ...children: any[]) => {
  // 仅用于类型兼容,实际会被Babel剥离
  return { tag, props, children };
};
export const jsxs = jsx;

配合tsconfig配置:

{
  "compilerOptions": {
    "jsx": "preserve",
    "jsxImportSource": "path/to/jsx-factory", 
    "jsxFactory": "jsx",
  }
}

路径配置正确(否则会有其他警告),但执行npx ts-node src/index.tsx时没有触发工厂函数的日志,不确定是否生效。

  • 发现一种不会触发警告且能识别引用的写法,但不够美观:
<UserDetails.name />
<UserDetails.call />

这种写法可以用Babel剥离,但不符合框架语法设计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 02:30:59