Bun TypeScript 支持 #
概述 #
Bun 原生支持 TypeScript,无需额外配置即可直接运行 .ts 文件。Bun 内置了 TypeScript 转译器,可以快速编译 TypeScript 代码。
快速开始 #
直接运行 TypeScript #
typescript
// index.ts
interface User {
name: string;
age: number;
}
const user: User = {
name: "Bun",
age: 3,
};
console.log(`Hello, ${user.name}!`);
bash
# 直接运行,无需编译
bun run index.ts
安装类型定义 #
bash
# 安装 Bun 类型
bun add -d bun-types
# 安装 Node.js 类型(兼容层)
bun add -d @types/node
tsconfig.json #
基本配置 #
json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ESNext"],
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"include": ["src/**/*", "index.ts"],
"exclude": ["node_modules"]
}
Bun 推荐配置 #
json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ESNext"],
"types": ["bun-types"],
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"jsxImportSource": "react",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*", "*.ts"],
"exclude": ["node_modules", "dist"]
}
配置选项说明 #
| 选项 | 说明 | 推荐值 |
|---|---|---|
target |
编译目标 | ESNext |
module |
模块系统 | ESNext |
moduleResolution |
模块解析策略 | bundler |
strict |
严格模式 | true |
skipLibCheck |
跳过库检查 | true |
noEmit |
不输出文件 | true |
jsx |
JSX 转换 | react-jsx |
类型系统 #
基本类型 #
typescript
// 原始类型
const name: string = "Bun";
const version: number = 1.2;
const isFast: boolean = true;
// 数组
const numbers: number[] = [1, 2, 3];
const names: Array<string> = ["a", "b", "c"];
// 元组
const tuple: [string, number] = ["Bun", 1];
// 对象
const obj: { name: string; age: number } = {
name: "Bun",
age: 3,
};
// any 和 unknown
let anything: any = "anything";
let safe: unknown = "safe";
接口 #
typescript
interface User {
id: number;
name: string;
email: string;
age?: number; // 可选属性
readonly createdAt: Date; // 只读属性
}
interface Admin extends User {
role: "admin";
permissions: string[];
}
const user: User = {
id: 1,
name: "Bun",
email: "bun@example.com",
createdAt: new Date(),
};
类型别名 #
typescript
type ID = string | number;
type Status = "pending" | "active" | "inactive";
type User = {
id: ID;
name: string;
status: Status;
};
type Point = {
x: number;
y: number;
};
type Vector = Point & {
z: number;
};
泛型 #
typescript
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}
const str = identity<string>("hello");
const num = identity(42); // 类型推断
// 泛型接口
interface Response<T> {
data: T;
status: number;
message: string;
}
// 泛型类
class Container<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
// 泛型约束
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
联合类型与交叉类型 #
typescript
// 联合类型
type StringOrNumber = string | number;
function format(input: StringOrNumber): string {
if (typeof input === "string") {
return input;
}
return input.toString();
}
// 交叉类型
type Name = { name: string };
type Age = { age: number };
type Person = Name & Age;
const person: Person = {
name: "Bun",
age: 3,
};
// 类型守卫
function isString(value: unknown): value is string {
return typeof value === "string";
}
路径映射 #
配置路径别名 #
json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"],
"@utils/*": ["./src/utils/*"],
"@types/*": ["./src/types/*"]
}
}
}
使用路径别名 #
typescript
// 不使用别名
import { Button } from "../../../components/Button";
import { formatDate } from "../../../utils/format";
// 使用别名
import { Button } from "@/components/Button";
import { formatDate } from "@utils/format";
Bun 配置 #
在 bunfig.toml 中配置:
toml
[run]
# Bun 自动读取 tsconfig.json 的路径映射
类型声明 #
声明文件 #
typescript
// types/global.d.ts
declare global {
interface Window {
customProperty: string;
}
var globalVar: number;
}
export {};
// types/module.d.ts
declare module "my-module" {
export function doSomething(): void;
export const version: string;
}
模块扩展 #
typescript
// 扩展现有模块
declare module "express" {
interface Request {
user?: {
id: string;
name: string;
};
}
}
环境声明 #
typescript
// env.d.ts
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly NODE_ENV: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
类型工具 #
工具类型 #
typescript
// Partial - 所有属性可选
type PartialUser = Partial<User>;
// Required - 所有属性必需
type RequiredUser = Required<User>;
// Pick - 选择属性
type UserName = Pick<User, "id" | "name">;
// Omit - 排除属性
type UserWithoutEmail = Omit<User, "email">;
// Record - 记录类型
type UserMap = Record<string, User>;
// ReturnType - 返回类型
function getUser() {
return { id: 1, name: "Bun" };
}
type User = ReturnType<typeof getUser>;
// Parameters - 参数类型
type UserParams = Parameters<typeof getUser>;
// NonNullable - 排除 null 和 undefined
type NonNullableString = NonNullable<string | null | undefined>;
条件类型 #
typescript
// 条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// infer 关键字
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type Result = UnwrapPromise<Promise<string>>; // string
映射类型 #
typescript
// 映射类型
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
type Optional<T> = {
[P in keyof T]?: T[P];
};
// 使用
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
type OptionalUser = Optional<User>;
类型检查 #
运行时检查 #
Bun 本身不进行类型检查,只进行转译。需要使用 tsc 进行类型检查:
bash
# 安装 TypeScript
bun add -d typescript
# 类型检查
bunx tsc --noEmit
# 添加到 package.json
{
"scripts": {
"typecheck": "tsc --noEmit"
}
}
类型检查脚本 #
typescript
// scripts/typecheck.ts
import { $ } from "bun";
try {
await $`tsc --noEmit`;
console.log("✅ Type check passed!");
} catch (error) {
console.error("❌ Type check failed!");
process.exit(1);
}
类型断言 #
typescript
// 类型断言
const value: unknown = "hello";
const str = value as string;
// 双重断言(不推荐)
const num = value as unknown as number;
// const 断言
const config = {
name: "Bun",
version: 1.2,
} as const;
// { readonly name: "Bun"; readonly version: 1.2 }
// 非空断言
const element = document.getElementById("app")!;
JSX 类型支持 #
React 类型 #
typescript
// 安装类型
bun add -d @types/react @types/react-dom
// 使用
import { useState, useEffect } from "react";
function Counter(): JSX.Element {
const [count, setCount] = useState<number>(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
自定义 JSX 类型 #
typescript
// types/jsx.d.ts
declare global {
namespace JSX {
interface IntrinsicElements {
"my-custom-element": {
customProp?: string;
};
}
}
}
最佳实践 #
项目结构 #
text
src/
├── index.ts
├── types/
│ ├── index.ts # 导出所有类型
│ ├── user.ts
│ ├── product.ts
│ └── api.ts
├── services/
│ ├── user.ts
│ └── product.ts
└── utils/
├── index.ts
└── helpers.ts
类型组织 #
typescript
// types/index.ts
export * from "./user";
export * from "./product";
export * from "./api";
// types/user.ts
export interface User {
id: string;
name: string;
email: string;
}
export type UserCreateInput = Omit<User, "id">;
export type UserUpdateInput = Partial<UserCreateInput>;
export interface UserResponse {
success: boolean;
data?: User;
error?: string;
}
严格模式 #
json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true
}
}
类型导入优化 #
typescript
// 使用 type 关键字明确类型导入
import type { User, Product } from "./types";
import { UserService } from "./services";
// 内联类型导入
import { UserService, type User } from "./services";
常见问题 #
模块解析问题 #
typescript
// 问题:找不到模块
import { something } from "./utils";
// 解决:确保扩展名正确或配置 paths
import { something } from "./utils/index.ts";
类型扩展问题 #
typescript
// 问题:类型扩展不生效
// 解决:确保声明文件被包含
// tsconfig.json
{
"include": ["src/**/*", "types/**/*"]
}
第三方库类型 #
bash
# 安装类型定义
bun add -d @types/express
bun add -d @types/lodash
# 或使用 DefinitelyTyped
bun add -d @types/node
下一步 #
现在你已经了解了 Bun 的 TypeScript 支持,接下来学习 JSX 支持 深入了解 Bun 的 JSX 转换功能。
最后更新:2026-03-29