如何调整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
相关产品推荐
相关产品推荐

