Zhin types for typescript
npm install @zhin.js/typesZhin 机器人框架的 TypeScript 类型定义包,提供完整的类型系统支持,确保类型安全的开发体验。
- 🎯 完整类型覆盖: 涵盖框架所有核心概念的类型定义
- 🔧 灵活扩展: 支持模块扩展和类型增强
- 🧩 上下文系统: 强大的依赖注入类型支持
- ⚡ 异步友好: 完整的 Promise/异步操作类型支持
- 📦 零依赖: 纯类型定义,无运行时依赖
框架的核心类型扩展点,所有模块都可以通过模块声明扩展此接口:
``typescript
// 基础接口定义
export interface GlobalContext extends Record
// 各模块扩展示例
declare module '@zhin.js/types' {
interface GlobalContext {
// HTTP 模块扩展
koa: Koa
router: Router
server: Server
// 数据库模块扩展
database: Database
redis: Redis
// 自定义扩展
myService: MyService
}
}
`
使用场景:
- 定义全局可用的服务
- 模块间类型共享
- 依赖注入类型声明
- IDE 智能提示支持
表示一个值可能是同步值或异步 Promise,提供灵活的异步编程支持:
`typescript
export type MaybePromise
// 使用示例
function flexibleAsync(): MaybePromise
if (Math.random() > 0.5) {
return 'sync result'
}
return Promise.resolve('async result')
}
// 处理 MaybePromise
async function handleResult(result: MaybePromise
const value = await Promise.resolve(result)
console.log(value) // 始终是字符串
}
`
应用场景:
- 中间件函数返回值
- 生命周期钩子函数
- 配置加载函数
- 插件初始化函数
从数组类型中提取元素类型的工具类型:
`typescript
export type ArrayItem
// 使用示例
type StringArray = string[]
type StringItem = ArrayItem
type NumberArray = number[]
type NumberItem = ArrayItem
// 复杂类型示例
type UserArray = Array<{ id: number; name: string }>
type User = ArrayItem
`
定义上下文依赖的副作用函数,支持清理函数返回:
`typescript
export type SideEffect =
(...args: Contexts) => MaybePromise
// 使用示例
const databaseEffect: SideEffect<['database', 'config']> =
async (db, config) => {
// 初始化数据库连接
await db.connect(config.url)
console.log('数据库已连接')
// 返回清理函数
return async (context) => {
await db.disconnect()
console.log('数据库连接已关闭')
}
}
// 无清理函数的副作用
const loggerEffect: SideEffect<['config']> = (config) => {
console.log('Logger initialized with config:', config)
// 不返回清理函数
}
`
定义资源清理函数的类型:
`typescript
export type DisposeFn = (context: ArrayItem) => MaybePromise
// 使用示例
const cleanupDatabase: DisposeFn
await db.close()
console.log('数据库已关闭')
}
const cleanupFile: DisposeFn
file.close()
console.log('文件已关闭')
}
`
从上下文键数组构建对应的上下文值类型数组:
`typescript
export type Contexts
CS extends [infer L, ...infer R]
? R extends (keyof GlobalContext)[]
? [ContextItem
: never[]
: never[]
// 内部工具类型
type ContextItem
// 使用示例
declare module '@zhin.js/types' {
interface GlobalContext {
database: Database
config: Config
logger: Logger
}
}
// 自动推导上下文类型
type MyContexts = Contexts<['database', 'config']> // [Database, Config]
type AllContexts = Contexts<['database', 'config', 'logger']> // [Database, Config, Logger]
`
`typescript`
// 在你的模块中扩展全局上下文
declare module '@zhin.js/types' {
interface GlobalContext {
// HTTP 服务
httpServer: {
start(port: number): Promise
stop(): Promise
}
// 缓存服务
cache: {
get
set
delete(key: string): boolean
}
// 事件总线
eventBus: {
emit(event: string, ...args: any[]): void
on(event: string, handler: Function): () => void
}
}
}
`typescript
import { SideEffect, MaybePromise } from '@zhin.js/types'
// 定义插件配置类型
interface MyPluginConfig {
apiKey: string
timeout: number
retries?: number
}
// 定义插件服务类型
interface MyPluginService {
request(url: string, options?: object): Promise
uploadFile(file: Buffer, filename: string): Promise
}
// 扩展全局上下文
declare module '@zhin.js/types' {
interface GlobalContext {
myPlugin: MyPluginService
}
}
// 实现副作用函数
const myPluginEffect: SideEffect<['config']> = async (config) => {
const service: MyPluginService = {
async request(url, options = {}) {
// 实现请求逻辑
return fetch(url, {
timeout: config.timeout,
...options
})
},
async uploadFile(file, filename) {
// 实现上传逻辑
return https://cdn.example.com/${filename}`
}
}
// 返回清理函数
return async () => {
console.log('MyPlugin service disposed')
}
}
`typescript
import { MaybePromise } from '@zhin.js/types'
// 定义中间件类型
type Middleware
context: T,
next: () => Promise
) => MaybePromise
// HTTP 中间件
type HttpMiddleware = Middleware<{
request: Request
response: Response
}>
// 消息中间件
type MessageMiddleware = Middleware<{
message: Message
user: User
}>
// 实现中间件
const authMiddleware: HttpMiddleware = async (ctx, next) => {
const token = ctx.request.headers.authorization
if (!token) {
ctx.response.status = 401
return
}
await next()
}
const rateLimitMiddleware: MessageMiddleware = async (ctx, next) => {
const userId = ctx.user.id
const isAllowed = await checkRateLimit(userId)
if (isAllowed) {
await next()
} else {
throw new Error('Rate limit exceeded')
}
}
`
`typescript
import { MaybePromise } from '@zhin.js/types'
// 定义生命周期钩子类型
interface LifecycleHooks {
beforeMount?: () => MaybePromise
mounted?: () => MaybePromise
beforeUpdate?: () => MaybePromise
updated?: () => MaybePromise
beforeDestroy?: () => MaybePromise
destroyed?: () => MaybePromise
}
// 实现组件
class Component implements LifecycleHooks {
async beforeMount() {
console.log('Component is about to mount')
}
mounted() {
console.log('Component mounted')
// 可以返回同步值
}
async beforeDestroy() {
await this.cleanup()
console.log('Component will be destroyed')
}
private async cleanup() {
// 异步清理逻辑
await new Promise(resolve => setTimeout(resolve, 100))
}
}
`
`typescript
import { MaybePromise } from '@zhin.js/types'
// 定义配置加载器类型
type ConfigLoader
// 应用配置类型
interface AppConfig {
port: number
database: {
url: string
pool: number
}
redis: {
host: string
port: number
}
}
// 实现配置加载器
const loadConfig: ConfigLoader
if (env.CONFIG_URL) {
// 异步加载远程配置
const response = await fetch(env.CONFIG_URL)
return response.json()
}
// 同步返回默认配置
return {
port: parseInt(env.PORT || '3000'),
database: {
url: env.DATABASE_URL || 'sqlite://./data.db',
pool: parseInt(env.DB_POOL || '10')
},
redis: {
host: env.REDIS_HOST || 'localhost',
port: parseInt(env.REDIS_PORT || '6379')
}
}
}
`
`typescript
// 根据输入类型推导输出类型
type InferResult
? U
: T extends Array
? V
: T
type StringResult = InferResult
type NumberResult = InferResult
type DirectResult = InferResult
`
`typescript
// 类型保护函数
function isPromise
return value && typeof (value as any).then === 'function'
}
// 使用类型保护
async function handleMaybePromise
if (isPromise(value)) {
return await value
}
return value
}
`
`typescript
// 组合多个工具类型
type OptionalPromise
type ArrayOrSingle
type ConfigValue
// 使用组合类型
const loadPlugins: () => ConfigValue
// 可以返回:
// - 'single-plugin'
// - ['plugin1', 'plugin2']
// - Promise.resolve('async-plugin')
// - Promise.resolve(['async1', 'async2'])
// - undefined
return Math.random() > 0.5 ? 'plugin' : ['plugin1', 'plugin2']
}
`
1. 使用模块声明扩展全局类型
2. 为异步操作使用 MaybePromise
3. 合理使用条件类型和类型推导
4. 提供完整的类型注解
5. 避免使用 any,优先使用 unknown`
- ✅ VSCode: 完整的 IntelliSense 支持
- ✅ WebStorm: 智能代码补全
- ✅ TypeScript: 严格的类型检查
- ✅ ESLint: TypeScript 规则支持
MIT License