Last active
September 28, 2018 02:19
-
-
Save snewell92/de233fbe11a5e4b159da1cf8e8f1b766 to your computer and use it in GitHub Desktop.
Typescript Dictionary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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... |
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"
}
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
Hi, I get this:
Type 'Record<K, V>[Extract<K, string>]' cannot be converted to type 'V'
Typescript 3.0.1