Reputation: 33046
I have a Dictionary class and I would like to do the following:
export class Dictionary<K, V> {
private table:{ [key: string]: IDictionaryPair<K, V> };
private nElements:number;
constructor(src:Dictionary<K, V>) {
for (var item in src.table)
if (src.hasOwnProperty(item)) {
windward.trap();
var valCopy = new V(src[<string>item]);
this.setValue(<K>item, valCopy);
}
}
}
This would all work great except "var valCopy = new V(src[item]);" is not allowed. Is there a way to do this? Because if the type V has a copy constructor, then this is all valid including type checking.
Is there a way to do this?
thanks - dave
Upvotes: 0
Views: 130
Reputation: 251262
All of the type information is erased at runtime, so you need something that will still exist at runtime in order to new up an instance:
export class Dictionary<K, V> {
private table:{ [key: string]: IDictionaryPair<K, V> };
private nElements:number;
constructor(src:Dictionary<K, V>, myType: any) {
for (var item in src.table)
if (src.hasOwnProperty(item)) {
windward.trap();
var valCopy = <V> new myType(src[<string>item]);
this.setValue(<K>item, valCopy);
}
}
}
You can even constrain it so you can guarantee the constructor signature is what you expect:
export interface MyNewable<T> {
new(input: string) : T;
}
export class Dictionary<K, V> {
private table:{ [key: string]: IDictionaryPair<K, V> };
private nElements:number;
constructor(src:Dictionary<K, V>, type: MyNewable<V>) {
for (var item in src.table)
if (src.hasOwnProperty(item)) {
windward.trap();
var valCopy = <V> new type(src[<string>item]);
this.setValue(<K>item, valCopy);
}
}
}
Example using the constrained version (simplified by not passing in a src
)
export class MyClass {
constructor(input: string) {
}
}
export class Example {
constructor(input: number) {
}
}
var d = new Dictionary<string, MyClass>(null, MyClass);
// Complier warning - type `Example` isn't compatible.
var e = new Dictionary<string, MyClass>(null, Example);
Upvotes: 1