As an intelligent exercise, I thought that I would see how I could implement some of the .Net generators in TypeScript (0.9.5), I got to List<T>, but not sure, I can progress.
(I understand that there are workarounds for this, but I'm specifically trying to use the same implementation as in .Net libs, mainly to try to understand the limitations still present in TypeScript).
In any case, ignoring the fact that I seem to be unable to overload my constructors in any meaningful way, in the .Net source the constructor List(IEnumerable<T> collection)checks that the passed Enumerable is not null and then drops it contravariantly to ICollection using ICollection<T> c = collection as ICollection<T>.
In TypeScript, I do this var c: ICollection<T> = collection(the collection is IEnumerable<T>), but gets the following error:
Cannot convert 'IEnumerable<T>' to 'ICollection<T>': Type 'IEnumerable<T>' is missing property 'Add' from type 'ICollection<T>'.
My current code is as follows:
export module System {
export module Collections {
export interface IEnumerator {
MoveNext(): boolean;
Reset(): void;
Current(): any;
}
export interface IEnumerable {
GetEnumerator(): IEnumerator;
}
export interface ICollection extends IEnumerable {
CopyTo(array: any[], index: number): void;
Count(): number;
SyncRoot(): any;
IsSynchronized(): boolean;
}
export interface IList extends ICollection {
[index: number]: any;
Add(value: any): number;
Contains(value: any): boolean;
Clear(): void;
IsReadOnly: boolean;
IsFixedSize: boolean;
IndexOf(value: any): number;
Insert(index: number, value: any): void;
Remove(value: any): void;
RemoveAt(index: number): void;
}
export module Generic {
export interface IEnumerator<T> extends System.Collections.IEnumerator {
Current(): T;
}
export interface IEnumerable<T> extends System.Collections.IEnumerable {
GetEnumerator(): IEnumerator<T>;
}
export interface ICollection<T> extends IEnumerable<T> {
Add(item: T): void;
Clear(): void;
Contains(item: T): boolean;
CopyTo(array: T[], arrayIndex: number): void;
Remove(item: T): boolean;
Count(): number;
IsReadOnly(); boolean;
}
export interface IList<T> extends ICollection<T> {
IndexOf(item: T): number;
Insert(index: number, item: T): void;
RemoveAt(index: number): void;
[index: number]: T;
}
export interface IReadOnlyCollection<T> extends IEnumerable<T> {
Count(): number;
}
export interface IReadOnlyList<T> extends IReadOnlyCollection<T> {
[index: number]: T;
}
export class List<T> implements IList<T>, System.Collections.IList, IReadOnlyList<T> {
private _defaultCapacity: number = 4;
private _items: T[];
private _size: number;
private _version: number;
private _syncRoot: any;
constructor(collection?: IEnumerable<T>, capacity?: number) {
if (collection == null) {
if (capacity == null) {
this._items = new Array<T>(0);
}
else {
this._items = new Array<T>(capacity);
}
} else {
var c: ICollection<T> = collection;
}
}
}
}
}
}
Has anyone else tried to match / contradict interfaces? If so, how are you?
Thanks,
source
share