如何为普通对象提供索引签名

时间:2018-03-16 17:20:51

标签: typescript typescript2.0 tsc

我有这个对象:

const events = {
  i: 'insert',
  u: 'update',
  d: 'delete'
};

出于某种原因,我在如何给对象一个索引签名 - 如果我这样做:

export interface EventsSignature {
  [key:string]: string
}

const events = <EventsSignature>{
  i: 'insert',
  u: 'update',
  d: 'delete'
};

不起作用,只是覆盖对象定义。注意我这样做有同样的问题:

export class OplogObservable {

  private uri: string;
  private coll: Collection;
  collName: string;
  isTailing = false;

  private subs = {
    all: new Subject<any>(),
    update: new Subject<Object>(),
    insert: new Subject<Object>(),
    delete: new Subject<Object>(),
    errors: new Subject<Object>(),
    end: new Subject<Object>()
  };

}

如果我new OplogObservable().subs[type],它会抱怨说没有索引签名。

1 个答案:

答案 0 :(得分:2)

对象文字已经有一个索引签名,只是你不能用任意字符串索引,它必须是该类型的键:

export class OplogObservable {

    private subs = {
        all: new Subject<any>(),
        update: new Subject<Object>(),
        insert: new Subject<Object>(),
        delete: new Subject<Object>(),
        errors: new Subject<Object>(),
        end: new Subject<Object>()
    };
    test(type: string) {
        this.subs['all'] // ok using a constant 
        let subs = this.subs;
        this.subs[type as keyof typeof subs] // ok if we use a type assertion on the key
    }
}

如果您真的想使用任意字符串进行索引,可以使用任何类型的断言:

 (this.subs as any)[type]

或使用辅助函数创建包含属性和索引器的对象:

function eventsHelper<T extends { [name: string] :Subject<any> }>(subs: T) : T & { [name: string] :Subject<any> }{
    return subs;
}
export class OplogObservable {

    private subs = eventsHelper({
        all: new Subject<any>(),
        update: new Subject<Object>(),
        insert: new Subject<Object>(),
        delete: new Subject<Object>(),
        errors: new Subject<Object>(),
        end: new Subject<Object>()
    });
    test(type: string) {
        this.subs.all // props preserved
        this.subs[type] // ok if we use a simple string to index
    }
}