Skip to content

Instantly share code, notes, and snippets.

@nickytonline
Created November 19, 2017 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickytonline/63f4988fef2b108f8299c0c16a4e8a4b to your computer and use it in GitHub Desktop.
Save nickytonline/63f4988fef2b108f8299c0c16a4e8a4b to your computer and use it in GitHub Desktop.
interface Association<TKey, TValue> {
key: TKey;
info: TValue;
}
interface StringKeyInfo {
keyIndexes: Array<Association<string, number>>;
keyIsSet: Array<Association<string, boolean>>;
}
function initializeStringKeyInfo(key: string): StringKeyInfo {
const keyIndexesDefault: Association<string, number> = { key, info: 0 };
const keyIsSetDefault: Association<string, boolean> = { key, info: true };
return {
keyIndexes: [keyIndexesDefault],
keyIsSet: [keyIsSetDefault]
};
}
class StringKeys {
private info = initializeStringKeyInfo("");
keys: [""];
}
@nickytonline
Copy link
Author

You can even omit the Association<T, U> from lines 12 and 13 as TypeScript can infer the proper type when it gets to the return value of StringKeyInfo.

@chriseppstein
Copy link

Ok, so, imagine a refactoring where we change the declaration of the member.

nterface Association<Key, Value> {
  key: Key;
  info: Value;
}

interface StringKeyInfo {
  keyIndexes: Array<Association<string, {v1: number, v2: number}>>; // new way of storing indexes
  keyIsSet: Array<Association<string, boolean>>;
}
class StringKeys {
  private info: StringKeyInfo;
  keys: Array<string>;
  constructor() {
    this.info = initializeStringKeyInfo("");
    this.keys = [""];
  }
  add(key: string) {
    let index = this.keys.length;
    this.info.keyIndexes.push({key, info: {v1: index, v2: -index}});
    this.info.keyIsSet.push({key, info: true});
  }
}

function initializeStringKeyInfo(key: string): StringKeyInfo {
  let keyIndexesDefault: Association<string, number> = {key, info: 0}; // not an error
  let keyIsSetDefault: Association<string, boolean> = {key, info: true};
  return {
    keyIndexes: [keyIndexesDefault],
    keyIsSet: [keyIsSetDefault]
  }; // big giant error
}

Here's the error message. With more complex types, this gets way worse.

test/utility-types-test.ts(37,3): error TS2322: Type '{ keyIndexes: Association<string, number>[]; keyIsSet: Association<string, boolean>[]; }' is not assignable totype 'StringKeyInfo'.
  Types of property 'keyIndexes' are incompatible.
    Type 'Association<string, number>[]' is not assignable to type 'Association<string, { v1: number; v2: number; }>[]'.
      Type 'Association<string, number>' is not assignable to type 'Association<string, { v1: number; v2: number; }>'.
        Type 'number' is not assignable to type '{ v1: number; v2: number; }'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment