如何使用TypeScript类型约束传递其他值

时间:2018-01-03 21:46:13

标签: typescript typescript2.0

我有一个像这样的泛型类但我想用T

传递额外的值
@Injectable()
export class Repository<T,// value //> {
   constructor(){
     let _value = value;
   }
}

-usage -

@Injectable()
export class ProductService {

  constructor(private repo: Repository<Product, //string or numeric value//>) {
  }

我想实现类似的东西,如何在typescript中传递带有泛型参数的字符串或数值。

1 个答案:

答案 0 :(得分:0)

泛型类型对类型参数感到满意,而不是文字值(虽然你可以用它做一些非常时髦的东西 - 但在你的情况下你不需要)。

您可以接受listType并将其限制为string或字符串文字类型,如下所示(它看起来像一个联合类型,但是有字符串值,因为它是类型成员)。

class Repository<T> {
  private itemsRef: T[];

  constructor(private db: AngularFireDatabase, listType: 'products' | 'customers') {
    this.itemsRef = db.list(listType);
  }
}

脆弱的部分是,消费者可以传递不兼容的TlistType - 因此您可能需要创建RepositioryFactory来阻止此操作。

工厂变更

以下是带有工厂方法的版本,可防止出现不兼容错误。

type ListType = 'products' | 'customers';

class Repository<T> {
  private itemsRef: T[];

  protected constructor(private db: AngularFireDatabase, listType: ListType) {
    this.itemsRef = db.list(listType);
  }

  static getInstance(db: AngularFireDatabase, listType: 'products'): Repository<Product>;
  static getInstance(db: AngularFireDatabase, listType: 'customers'): Repository<Customer>;
  static getInstance(db: AngularFireDatabase, listType: ListType) {
    switch (listType) {
      case 'products':
        return new Repository<Product>(db, listType);
      case 'customers':
        return new Repository<Customer>(db, listType);
      default:
        throw new Error(`No Respository<T> for ${listType}`);
    }
  }
}