Edit: I've updated the code and uploaded [a gist](https://gist.github.com/snewell92/de233fbe11a5e4b159da1cf8e8f1b766) that will work in the [TS playground](http://www.typescriptlang.org/play/) - the gist will compile with Typescript 3.0's strictest settings (at least all the strict settings available to the playground). The primary benefit of Typescript is to provide types for Javascript. And since [Typescript provides Generics](https://www.typescriptlang.org/docs/handbook/generics.html) - I don't think your implementation of a Dictionary provides any benefit over a plain javascript object. In fact, as you noted in the comments, JS Objects (ie TS object) _are_ dictionaries. You just need to provide types around them for your dictionary. (btw - I also come from a C# background, but I've also come to love the underlying functional nature of JS that TS lets us type). Here's a code sample of the direction I would expect a `Dictionary.ts` class to have in a code base I work in. Now that we have [Mapped Types](https://github.com/Microsoft/TypeScript/pull/12114), we can [generalize dictionaries better](http://www.rickcarlino.com/2017/02/27/Real-World-Use-Case-For-Typescript-Record-Types/). export interface Dictionary<K, V> { getKeys(): K[]; getValues(): V[]; get(key: K): V; put(key: K, val: V): void; // or boolean? } export class JSDictionary<K extends string, V> implements Dictionary<K, V> { private internalDict: Partial<Record<K, V>>; constructor() { this.internalDict = {}; } public getKeys(): K[] { let keys: K[] = []; for(let key in this.internalDict) { keys.push(key); } return keys; } public getValues(): V[] { let vals: V[] = []; for(let key in this.internalDict) { vals.push(this.internalDict[key]); } return vals; } public get(key: K): V { return this.internalDict[key]; } public put(key: K, val: V): void { this.internalDict[key] = val; } } Example Usage type myKeys = 'FOX' | 'CAT' | 'DOG'; interface Animal { species: string; name: string; weight: number; } // A dictionary that hols one fox/cat/dog. let myAnimalPen = new JSDictionary<myKeys, Animal>(); myAnimalPen.put('FOX', { name: 'Foxworth', species: 'Fox', weight: 40 }); // a dictionary that takes any string and maps it to a number let idDict = new JSDictionary<string, number>(); idDict.put('somehas', 1204); idDict.put('yeahaasd', 3306); let yeaID = idDict.get('yeahaasd'); // yeaID is a number type let myFox = myAnimalPen.get('FOX'); // myFox is an Animal type Major points: - Code to an interface as much as you can in typescript. Affords you flexibility - *Generic types* - Transparent use of Plain JS object as the underlying dictionary (JS Engines optimize this very use case!) - I removed overloaded constructors, but you could add that back in with the proper types and it will work as expected - Left out clone - pretty easy to implement though - No exception handling when get returns null, like your 'try*' functions. I actually like try functions like you have, so you could mostly copy/paste, although with the stricter typings sometimes that will be taken care of by the compiler for you.