Skip to content

Instantly share code, notes, and snippets.

@snewell92
Last active September 28, 2018 02:19
Show Gist options
  • Save snewell92/de233fbe11a5e4b159da1cf8e8f1b766 to your computer and use it in GitHub Desktop.
Save snewell92/de233fbe11a5e4b159da1cf8e8f1b766 to your computer and use it in GitHub Desktop.
Typescript Dictionary
type KEY = string | number | symbol;
interface Dictionary<K extends KEY, V> {
getKeys(): K[];
getValues(): V[];
get(key: K): V | null;
put(key: K, val: V): void; // or boolean?
}
class JSDict<K extends KEY, V> implements Dictionary<K, V> {
private dict: { [key in K]?: V };
constructor() {
this.dict = {};
}
public getKeys() {
let keys: K[] = [];
for(let key in this.dict) {
keys.push(key);
}
return keys;
}
public getValues() {
let vals: V[] = [];
for (let key in this.dict) {
let v = this.dict[key];
if (this.exists(v)) {
vals.push(v);
}
}
return vals;
}
// Type predicate to ensure v exists
private exists(v: V | undefined): v is V {
return v != null && typeof v !== "undefined";
}
public get(key: K) {
let v = this.dict[key];
return this.exists(v)
? v
: null;
}
public put(key: K, val: V) {
this.dict[key] = val;
}
static Create<Keys extends KEY, Values>() {
return new JSDict<Keys, Values>();
}
}
type Fruits = "Apples" | "Bananas" | "Oranges";
var d = JSDict.Create<Fruits, number>();
d.put("Bananas", 5);
// etc...
@coignite-user
Copy link

Hi, I get the following:

Line 30: let v = this.dict[key] as V;
TS2352: Type 'Record<K, V>[Extract<K, string>]' cannot be converted to type 'V'.

Line 38: return this.dict[key] as V;
TS2352: Type 'Record<K, V>[K]' cannot be converted to type 'V'.

Line 42: this.dict[key] = val;
TS2322: Type 'V' is not assignable to type 'Record<K, V>[K]'.

My tsconfig:

{
  "compilerOptions": {
    "outDir": "lib",
    "noImplicitAny": true,
    "sourceMap": true,
    "declaration": true,
    "module": "es6",
    "target": "es5"
  }
}

My package dependencies:

  "devDependencies": {
    "clean-webpack-plugin": "^0.1.19",
    "html-webpack-plugin": "^3.2.0",
    "source-map-loader": "^0.2.4",
    "ts-loader": "^5.1.0",
    "typescript": "^3.0.3",
    "webpack": "^4.18.0",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.8",
    "webpack-merge": "^4.1.4",
    "xmlhttprequest": "^1.8.0"
  }

@snewell92
Copy link
Author

Maybe I should just use mapped types directly - rewrite incoming

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