# AkSupa executeAs<T>() 类型转换功能

## 概述

AkSupa 现在提供简洁的 `executeAs<T>()` 方法，支持链式请求的类型转换功能，可以直接返回指定的类型而不仅仅是 `UTSJSONObject`。

## 设计理念

遵循 **简洁性原则**，只提供一个 `executeAs<T>()` 方法来处理所有类型转换需求，因为：

1. **统一API**：所有操作最终都通过 `execute()` 处理，`executeAs<T>()` 是其类型安全版本
2. **链式友好**：可以与所有现有的链式方法无缝组合
3. **易于理解**：只需记住一个方法，降低学习成本
4. **功能完整**：覆盖查询、插入、更新、删除、RPC 等所有操作

## 平台兼容性

| 平台 | 支持方式 | 说明 |
|------|----------|------|
| Android (uni-app x 3.90+) | `UTSJSONObject.parse()` | 真正的类型转换 |
| Web | `as T` | 类型断言，编译时类型提示 |
| iOS | `as T` | 类型断言，编译时类型提示 |
| HarmonyOS (4.61+) | `UTSJSONObject.parse()` | 真正的类型转换 |

## 方法签名

```typescript
async executeAs<T>() : Promise<AkReqResponse<T>>
```

## 使用示例

### 1. 定义数据类型

```typescript
export type User = {
    id: number;
    name: string;
    email: string;
    created_at: string;
    avatar_url?: string;
}
```

### 2. 查询操作

```typescript
// 查询多条记录
const usersResult = await supa
    .from('users')
    .select('*')
    .eq('status', 'active')
    .limit(10)
    .executeAs<User[]>();

// 查询单条记录
const userResult = await supa
    .from('users')
    .select('*')
    .eq('id', 1)
    .single()
    .executeAs<User>();

// 复杂查询
const complexQuery = await supa
    .from('posts')
    .select('*, users!posts_user_id_fkey(*)')
    .eq('status', 'published')
    .gt('created_at', '2024-01-01')
    .order('created_at', { ascending: false })
    .limit(20)
    .executeAs<Post[]>();
```

### 3. 插入操作

```typescript
const newUser = {
    name: '新用户',
    email: 'newuser@example.com'
} as UTSJSONObject;

const insertResult = await supa
    .from('users')
    .insert(newUser)
    .executeAs<User[]>();
```

### 4. 更新操作

```typescript
const updateResult = await supa
    .from('users')
    .update({ name: '更新的名称' } as UTSJSONObject)
    .eq('id', 1)
    .executeAs<User[]>();
```

### 5. 删除操作

```typescript
const deleteResult = await supa
    .from('users')
    .delete()
    .eq('id', 1)
    .executeAs<User[]>();
```

### 6. RPC 调用

```typescript
const rpcResult = await supa
    .from('') // RPC 不需要 table
    .rpc('get_user_stats', { user_id: 1 } as UTSJSONObject)
    .executeAs<{ total_posts: number; total_likes: number }>();
```

## 错误处理

```typescript
try {
    const result = await supa
        .from('users')
        .select('*')
        .executeAs<User[]>();
    
    if (result.error) {
        console.error('查询失败:', result.error);
        return;
    }
    
    // 使用类型化的数据
    const users = result.data;
    if (users != null) {
        users.forEach(user => {
            // 现在有完整的类型提示
            console.log(user.name, user.email);
        });
    }
} catch (error) {
    console.error('请求异常:', error);
}
```

## 向后兼容性

- 原有的 `execute()` 方法依然保持不变，返回 `UTSJSONObject`
- 所有原有的链式方法都继续正常工作
- `executeAs<T>()` 是附加功能，不影响现有代码

## 对比旧版本

### 旧版本（多方法）
```typescript
// 需要记住多个方法
const users = await supa.selectAs<User[]>('users', filter, options);
const inserted = await supa.insertAs<User>('users', data);
const updated = await supa.updateAs<User[]>('users', filter, values);
const deleted = await supa.deleteAs<User[]>('users', filter);
const rpcResult = await supa.rpcAs<Stats>('func_name', params);
```

### 新版本（统一方法）
```typescript
// 只需记住一个 executeAs<T>() 方法
const users = await supa.from('users').select('*').executeAs<User[]>();
const inserted = await supa.from('users').insert(data).executeAs<User>();
const updated = await supa.from('users').update(values).eq('id', 1).executeAs<User[]>();
const deleted = await supa.from('users').delete().eq('id', 1).executeAs<User[]>();
const rpcResult = await supa.from('').rpc('func_name', params).executeAs<Stats>();
```

## 优势

1. **API 简洁**：只需要记住一个 `executeAs<T>()` 方法
2. **链式友好**：与所有现有方法完美组合
3. **类型安全**：编译时检查 + 运行时转换（Android）
4. **易于维护**：减少重复代码，统一处理逻辑
5. **学习成本低**：从 `execute()` 到 `executeAs<T>()` 自然过渡

## 注意事项

1. `UTSJSONObject.parse()` 仅在 Android 3.90+ 和 HarmonyOS 4.61+ 平台支持
2. 其他平台使用类型断言，主要提供编译时类型检查
3. 类型转换失败时会 fallback 到原始数据
4. 建议在生产环境中进行充分的测试

## 技术实现

`executeAs<T>()` 内部：
1. 调用原有的 `execute()` 方法获取结果
2. 在 Android 平台使用 `UTSJSONObject.parse()` 进行类型转换
3. 在其他平台使用类型断言提供类型提示
4. 返回类型化的 `AkReqResponse<T>` 结果
