message: ts: support checking key type on HashMap
diff: @@ -646,19 +646,20 @@ export function isPrimitive(obj: any): boolean {
  return obj[primitiveKey];
  }
  +
  /**
  * @constructor
  * @param {Object} obj Only apply `ownProperty`.
  */
  -export class HashMap<T> {
  +export class HashMap<T, KEY extends string | number = string | number> {
  - data: {[key: string]: T} = {}
  + data: {[key in KEY]: T} = {} as {[key in KEY]: T};
  - constructor(obj?: HashMap<T> | Dictionary<T> | any[]) {
  + constructor(obj?: HashMap<T, KEY> | Dictionary<T> | any[]) {
  const isArr = isArray(obj);
  // Key should not be set on this, otherwise
  // methods get/set/... may be overrided.
  - this.data = {};
  + this.data = {} as {[key in KEY]: T};
  const thisMap = this;
  (obj instanceof HashMap)
  @@ -673,10 +674,10 @@ export class HashMap<T> {
  // Do not provide `has` method to avoid defining what is `has`.
  // (We usually treat `null` and `undefined` as the same, different
  // from ES6 Map).
  - get(key: string | number): T {
  + get(key: KEY): T {
  return this.data.hasOwnProperty(key) ? this.data[key] : null;
  }
  - set(key: string | number, value: T) {
  + set(key: KEY, value: T) {
  // Comparing with invocation chaining, `return value` is more commonly
  // used in this case: `const someVal = map.set('a', genVal());`
  return (this.data[key] = value);
  @@ -684,24 +685,25 @@ export class HashMap<T> {
  // Although util.each can be performed on this hashMap directly, user
  // should not use the exposed keys, who are prefixed.
  each<Context>(
  - cb: (this: Context, value?: T, key?: string) => void,
  + cb: (this: Context, value?: T, key?: KEY) => void,
  context?: Context
  ) {
  - context !== void 0 && (cb = bind(cb, context));
  - /* eslint-disable guard-for-in */
  for (let key in this.data) {
  - this.data.hasOwnProperty(key) && (cb as any)(this.data[key], key);
  + if (this.data.hasOwnProperty(key)) {
  + cb.call(context, this.data[key], key);
  + }
  }
  - /* eslint-enable guard-for-in */
  }
  // Do not use this method if performance sensitive.
  - removeKey(key: string | number) {
  + removeKey(key: KEY) {
  delete this.data[key];
  }
  }
  -export function createHashMap<T>(obj?: HashMap<T> | Dictionary<T> | any[]) {
  - return new HashMap<T>(obj);
  +export function createHashMap<T, KEY extends string | number = string | number>(
  + obj?: HashMap<T, KEY> | Dictionary<T> | any[]
  +) {
  + return new HashMap<T, KEY>(obj);
  }
  export function concatArray<T, R>(a: ArrayLike<T>, b: ArrayLike<R>): ArrayLike<T | R> {
  