模板定义 API
defineTemplate、defineMock、TemplateProps、TemplateDef、DataOf 的签名与示例
写模板时直接 import 的 API,全部来自 @karinjs/template-react 主入口。
defineTemplate
declare const : <>(: <<>, '__data'>) => <>把「一个 React 组件 + 展示元信息」登记成模板。运行时不做加工、原样返回——价值在类型:数据类型 D 留在返回值里供一路推导。组件 props 已标注 TemplateProps<D> 时泛型自动推断;内联匿名组件再显式写 defineTemplate<D>({...})。
字段结构如下(由源码 JSDoc 自动生成):
Prop
Type
import { , type } from '@karinjs/template-react'
/** Hello 列表模板的数据结构。 */
export interface HelloListData {
: string
: <{ : string; : string; : number }>
}
const = ({ }: <HelloListData>) => (
< ="w-[640px] bg-background p-7 text-foreground">
< ="mb-5 text-2xl font-bold">{.}</>
{/* 遍历 data.users 渲染列表行…… */}
</>
)
export default ({
: '成员榜单',
: '多行重复的列表截图示例',
:
})只有 index.tsx 里默认导出 defineTemplate(...) 这一种写法会注册为 <板块>/<模板> 路由。
validate 示例(动态路由场景的兜底,不通过时报 Template data validation failed):
export default ({
: ,
: (): is ReceiptTallData =>
typeof === 'object' &&
!== null &&
typeof ( as ReceiptTallData). === 'string' &&
.(( as ReceiptTallData).)
})defineMock
declare const : <>(: ) => 定义一份类型安全的 TS mock,原样返回。写在模板的 mock.ts(固定文件名)里具名导出,面板中只读。与 satisfies 写法效果相同:
import { } from '@karinjs/template-react'
export const = <HelloListData>({
: '模板贡献榜',
: [{ : '林小满', : '模板作者', : 98 }]
})TemplateProps
interface <> {
/** 当前模板使用的数据,类型由 defineTemplate 的泛型决定。 */
:
/** ktr 注入的运行时上下文。 */
: RenderContext
}每个模板组件都会收到的 props。ctx.scale 是渲染比例(由外壳统一施加 zoom,模板无需处理,通常保持 1);ctx.theme 是调用方显式提供的主题变量,没传就是 undefined(框架不发明默认主题色),深色模式读 ctx.theme?.mode。ctx 上还可能携带调用方自定义的扩展字段(类型 unknown,读取时自行收窄),原样透传、框架不消费。
TemplateDef
defineTemplate 参数和返回值的结构,字段同上表。隐藏字段 __data?: D 仅作类型占位(运行时从不读取),作用是把 D 保留在定义上供 DataOf 提取,日常不用手写。
DataOf
type <> = extends <infer > ? : never从模板定义类型里取出数据类型 D,典型用法是渲染封装:
const = async < extends keyof & string>(: , : <[]>) => {
/* ... */
}K 是路由字面量,DataOf<Registry[K]> 是该模板的数据类型——写 renderImage('hello/card', {...}) 时 data 写错编译期报红。
逐路由精确类型来自 .ktr/registry-types.d.ts 的模块增强(ktr sync 生成),插件源码不需要 import .ktr
里的任何文件;类型突然「不灵了」时先跑一次 pnpm ktr sync。