17
Type-safe Dictionary in TypeScript
Although Map
object has almost everything I need, I recently found myself in need of map()
function on a Map
object... No such luck. ;)
So I implemented it.
export interface IDictionary<T> {
set(key: string, value: T);
get(key: string): T;
delete(key: string): boolean;
hasKey(key: string): boolean;
hasValue(value: T): boolean;
getKeys(): string[];
getValues(): T[];
map(fn: (key: string, value: T) => any ): {};
size: number;
}
export class Dictionary<T> implements IDictionary<T>{
private items: { [key: string]: T } = {};
public set(key: string, value: T) {
this.items[key] = value;
}
public get(key: string): T {
return this.items[key];
}
public delete(key: string):boolean {
if (this.items.hasOwnProperty(key)) {
delete this.items[key];
return true;
}
else {
return false;
}
}
public hasKey(key: string): boolean {
return this.items.hasOwnProperty(key);
}
public hasValue(value:T): boolean {
return Object.values(this.items).includes(value);
}
public getKeys(): string[] {
return Object.keys(this.items);
}
public getValues(): T[] {
return Object.values(this.items);
}
public map(mapFn: { (key: string, value:T): any; }): {} {
return Object.keys(this.items).map((key) => {
return mapFn(key,this.items[key]);
});
}
public format(mapFn: { (key: string, value:T): any; }): any[] {
return Object.keys(this.items).map((key) => {
return mapFn(key,this.items[key]);
});
}
public get size(): number {
return Object.keys(this.items).length;
}
}
Now, printing Dictionary in a React function couldn't be easier
export default function CommitForm(props: ICommitFormProps) {
let myDictionary: Dictionary<Array<string>> = (new Dictionary());
...
return (
<ul>
{
myDictionary.map((key: string, value: string[]) => {
return (<li>{value.join(", ")} (type {key}) </li>);
})
}
</ul>
);
...
}
And in case you want to use the Dictionary in your localized string:
Warning_HTML: string;
"Warning_HTML":"The following values are not supported:<ul>{0}</ul>"
export default function CommitForm(props: ICommitFormProps) {
let myDictionary: Dictionary<Array<string>> = (new Dictionary());
...
function getHTML(fields: Dictionary<string[]>): string {
return (fields.format((key, value) => { return "<li>" + value.join(", ") + " (type " + key + ") </li>"; })).join();
}
return (
<MessageBar messageBarType={MessageBarType.warning} isMultiline={true} >
{
<div dangerouslySetInnerHTML={{ __html: format(strings.Warning_HTML, getHTML(myDictionary)) }} ></div>
}
</MessageBar>
);
...
}
The difference between Object
, Map
and Record
is widely documented (see e.g. Building a type-safe dictionary in TypeScript for an explanation).
17