convert.ts•11.8 kB
// convert 工具实现
export async function convert(args: any) {
try {
const code = args?.code || "";
const from = args?.from || "";
const to = args?.to || "";
const message = `请转换以下代码:
📝 **源代码**:
${code || "请提供需要转换的代码"}
🔄 **转换类型**:${from} → ${to}
---
## 代码转换指南
### 支持的转换类型
#### 语言转换
- JavaScript → TypeScript
- TypeScript → JavaScript
- Python → JavaScript
- CommonJS → ESM
#### 框架转换
- Class Component → Hooks
- Vue 2 → Vue 3
- AngularJS → React
- jQuery → Vanilla JS
#### 样式转换
- CSS → Tailwind CSS
- SCSS → CSS-in-JS
- Styled-components → Emotion
#### 数据格式转换
- JSON → TypeScript Interface
- GraphQL → REST
- XML → JSON
---
## 转换示例
### 1️⃣ JavaScript → TypeScript
**JavaScript (Before):**
\`\`\`javascript
function calculateTotal(items, discount) {
const subtotal = items.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
return discount ? subtotal * (1 - discount) : subtotal;
}
const order = {
id: '123',
items: [
{ name: 'Book', price: 29.99, quantity: 2 },
{ name: 'Pen', price: 1.99, quantity: 5 }
],
discount: 0.1
};
const total = calculateTotal(order.items, order.discount);
\`\`\`
**TypeScript (After):**
\`\`\`typescript
interface Item {
name: string;
price: number;
quantity: number;
}
interface Order {
id: string;
items: Item[];
discount?: number;
}
function calculateTotal(items: Item[], discount?: number): number {
const subtotal = items.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
return discount ? subtotal * (1 - discount) : subtotal;
}
const order: Order = {
id: '123',
items: [
{ name: 'Book', price: 29.99, quantity: 2 },
{ name: 'Pen', price: 1.99, quantity: 5 }
],
discount: 0.1
};
const total: number = calculateTotal(order.items, order.discount);
\`\`\`
**✅ 转换要点**:
1. 添加类型接口定义
2. 函数参数和返回值添加类型注解
3. 变量添加类型声明(可选)
4. 可选属性用 \`?\` 标记
---
### 2️⃣ Class Component → React Hooks
**Class Component (Before):**
\`\`\`jsx
import React, { Component } from 'react';
class UserProfile extends Component {
constructor(props) {
super(props);
this.state = {
user: null,
loading: true,
error: null
};
}
componentDidMount() {
this.fetchUser();
}
componentDidUpdate(prevProps) {
if (prevProps.userId !== this.props.userId) {
this.fetchUser();
}
}
componentWillUnmount() {
this.abortController?.abort();
}
async fetchUser() {
this.setState({ loading: true });
this.abortController = new AbortController();
try {
const response = await fetch(\`/api/users/\${this.props.userId}\`, {
signal: this.abortController.signal
});
const user = await response.json();
this.setState({ user, loading: false });
} catch (error) {
if (error.name !== 'AbortError') {
this.setState({ error: error.message, loading: false });
}
}
}
render() {
const { user, loading, error } = this.state;
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!user) return null;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
}
export default UserProfile;
\`\`\`
**Hooks (After):**
\`\`\`tsx
import React, { useState, useEffect } from 'react';
interface User {
name: string;
email: string;
}
interface UserProfileProps {
userId: string;
}
const UserProfile: React.FC<UserProfileProps> = ({ userId }) => {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const abortController = new AbortController();
async function fetchUser() {
setLoading(true);
setError(null);
try {
const response = await fetch(\`/api/users/\${userId}\`, {
signal: abortController.signal
});
const userData = await response.json();
setUser(userData);
} catch (err) {
if (err instanceof Error && err.name !== 'AbortError') {
setError(err.message);
}
} finally {
setLoading(false);
}
}
fetchUser();
return () => {
abortController.abort();
};
}, [userId]); // userId 变化时重新获取
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!user) return null;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
};
export default UserProfile;
\`\`\`
**✅ 转换要点**:
1. \`constructor\` + \`this.state\` → \`useState\`
2. \`componentDidMount\` + \`componentDidUpdate\` → \`useEffect\`
3. \`componentWillUnmount\` → \`useEffect\` 清理函数
4. \`this.props\` → 函数参数
5. \`this.setState\` → \`setState\` 函数
6. 类方法 → 函数内部函数或自定义 Hook
---
### 3️⃣ Promises → Async/Await
**Promises (Before):**
\`\`\`javascript
function getUserData(userId) {
return fetch(\`/api/users/\${userId}\`)
.then(response => {
if (!response.ok) {
throw new Error('User not found');
}
return response.json();
})
.then(user => {
return fetch(\`/api/posts?userId=\${user.id}\`);
})
.then(response => response.json())
.then(posts => {
return { user, posts };
})
.catch(error => {
console.error('Error:', error);
throw error;
});
}
// 使用
getUserData('123')
.then(data => console.log(data))
.catch(error => console.error(error));
\`\`\`
**Async/Await (After):**
\`\`\`javascript
async function getUserData(userId) {
try {
const userResponse = await fetch(\`/api/users/\${userId}\`);
if (!userResponse.ok) {
throw new Error('User not found');
}
const user = await userResponse.json();
const postsResponse = await fetch(\`/api/posts?userId=\${user.id}\`);
const posts = await postsResponse.json();
return { user, posts };
} catch (error) {
console.error('Error:', error);
throw error;
}
}
// 使用
try {
const data = await getUserData('123');
console.log(data);
} catch (error) {
console.error(error);
}
\`\`\`
**✅ 转换要点**:
1. 函数前加 \`async\` 关键字
2. \`.then()\` → \`await\`
3. \`.catch()\` → \`try/catch\`
4. Promise 链条变为顺序执行
5. 代码更易读,像同步代码
---
### 4️⃣ CSS → Tailwind CSS
**CSS (Before):**
\`\`\`css
.button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.5rem 1rem;
font-size: 0.875rem;
font-weight: 500;
border-radius: 0.375rem;
background-color: #3b82f6;
color: white;
transition: background-color 0.2s;
}
.button:hover {
background-color: #2563eb;
}
.button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.button-lg {
padding: 0.75rem 1.5rem;
font-size: 1rem;
}
\`\`\`
**Tailwind CSS (After):**
\`\`\`jsx
// 基础按钮
<button className="inline-flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white transition-colors hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed">
Button
</button>
// 大按钮
<button className="inline-flex items-center justify-center px-6 py-3 text-base font-medium rounded-md bg-blue-600 text-white transition-colors hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed">
Large Button
</button>
// 或使用组件抽象
const Button = ({ size = 'default', children, ...props }) => {
const sizeClasses = {
default: 'px-4 py-2 text-sm',
lg: 'px-6 py-3 text-base'
};
return (
<button
className={\`
inline-flex items-center justify-center font-medium rounded-md
bg-blue-600 text-white transition-colors
hover:bg-blue-700
disabled:opacity-50 disabled:cursor-not-allowed
\${sizeClasses[size]}
\`}
{...props}
>
{children}
</button>
);
};
\`\`\`
**✅ Tailwind 类名对照表**:
| CSS 属性 | Tailwind 类名 |
|----------|---------------|
| \`display: flex\` | \`flex\` |
| \`align-items: center\` | \`items-center\` |
| \`justify-content: center\` | \`justify-center\` |
| \`padding: 0.5rem 1rem\` | \`px-4 py-2\` |
| \`font-size: 0.875rem\` | \`text-sm\` |
| \`font-weight: 500\` | \`font-medium\` |
| \`border-radius: 0.375rem\` | \`rounded-md\` |
| \`background-color: #3b82f6\` | \`bg-blue-600\` |
| \`color: white\` | \`text-white\` |
---
### 5️⃣ CommonJS → ESM
**CommonJS (Before):**
\`\`\`javascript
// math.js
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
module.exports = {
add,
multiply
};
// main.js
const { add, multiply } = require('./math');
const lodash = require('lodash');
console.log(add(2, 3));
\`\`\`
**ESM (After):**
\`\`\`javascript
// math.js
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// 或默认导出
// export default { add, multiply };
// main.js
import { add, multiply } from './math.js';
import lodash from 'lodash';
console.log(add(2, 3));
\`\`\`
**✅ 转换要点**:
1. \`module.exports\` → \`export\` / \`export default\`
2. \`require()\` → \`import\`
3. 文件扩展名:ESM 中通常需要 \`.js\`
4. \`package.json\` 需要设置 \`"type": "module"\`
---
### 6️⃣ JSON → TypeScript Interface
**JSON (Before):**
\`\`\`json
{
"id": "123",
"name": "John Doe",
"email": "john@example.com",
"age": 30,
"isActive": true,
"roles": ["admin", "user"],
"address": {
"street": "123 Main St",
"city": "New York",
"zipCode": "10001"
},
"metadata": {
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-15T00:00:00Z"
}
}
\`\`\`
**TypeScript Interface (After):**
\`\`\`typescript
interface Address {
street: string;
city: string;
zipCode: string;
}
interface Metadata {
createdAt: string; // 或 Date
updatedAt: string; // 或 Date
}
interface User {
id: string;
name: string;
email: string;
age: number;
isActive: boolean;
roles: string[];
address: Address;
metadata: Metadata;
}
// 使用
const user: User = {
id: "123",
name: "John Doe",
email: "john@example.com",
age: 30,
isActive: true,
roles: ["admin", "user"],
address: {
street: "123 Main St",
city: "New York",
zipCode: "10001"
},
metadata: {
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-15T00:00:00Z"
}
};
\`\`\`
---
## 转换注意事项
### ⚠️ 潜在问题
1. **类型安全**
- 转换后需要添加类型检查
- 注意 null/undefined 处理
2. **API 差异**
- 不同框架的生命周期不同
- 状态管理方式不同
3. **性能影响**
- 某些转换可能影响性能
- 需要测试和优化
4. **依赖更新**
- 检查依赖包兼容性
- 更新 package.json
---
现在请根据需求进行代码转换,提供:
1. 转换后的完整代码
2. 关键变更说明
3. 潜在问题提示
4. 迁移步骤(如需要)`;
return {
content: [
{
type: "text",
text: message,
},
],
};
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error);
return {
content: [
{
type: "text",
text: `❌ 代码转换失败: ${errorMessage}`,
},
],
isError: true,
};
}
}