Ember与TypeScript #

一、TypeScript配置 #

1.1 安装 #

bash
ember install ember-cli-typescript
npm install --save-dev @types/ember

1.2 配置 #

json
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "noImplicitAny": true,
    "experimentalDecorators": true
  },
  "include": ["app/**/*", "tests/**/*"]
}

二、类型定义 #

2.1 组件类型 #

typescript
// app/components/user-card.ts
import Component from '@glimmer/component';

interface UserCardSignature {
  Args: {
    user: User;
    size?: 'small' | 'medium' | 'large';
    onEdit?: (user: User) => void;
  };
  Blocks: {
    default: [user: User];
  };
  Element: HTMLDivElement;
}

export default class UserCardComponent extends Component<UserCardSignature> {
  get cardClass(): string {
    return `card card-${this.args.size || 'medium'}`;
  }
}

2.2 模型类型 #

typescript
// app/models/post.ts
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';

export default class PostModel extends Model {
  @attr('string') declare title: string;
  @attr('string') declare body: string;
  @attr('date') declare createdAt: Date;
  @belongsTo('user') declare author: User;
  @hasMany('comment') declare comments: Comment[];
}

2.3 服务类型 #

typescript
// app/services/session.ts
import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';

interface User {
  id: string;
  name: string;
  email: string;
}

export default class SessionService extends Service {
  @tracked isAuthenticated = false;
  @tracked currentUser: User | null = null;

  async login(email: string, password: string): Promise<User> {
    // ...
  }
}

三、类型声明 #

3.1 全局类型 #

typescript
// types/global.d.ts
declare module 'my-app/services/session' {
  import Service from '@ember/service';
  export default class SessionService extends Service {
    isAuthenticated: boolean;
    currentUser: User | null;
  }
}

四、总结 #

TypeScript集成要点:

概念 说明
Signature 组件类型定义
declare 模型属性声明
interface 接口定义

TypeScript提供更好的开发体验和类型安全。

最后更新:2026-03-28