TypeScript中的界面反差异

Tom*_*nna 4 .net javascript c# typescript

作为一个智力练习,我想我会看到我能够在TypeScript(0.9.5)中实现一些.Net泛型成员的程度,我已经得到了尽可能的List<T>但不确定我能不能进步.

(我意识到有这方面的解决方法,但我特别尝试使用与.Net库中存在的相同的实现,主要是尝试了解TypeScript中仍然存在的限制).

无论如何,忽略了我似乎无法以任何有意义的方式重载我的构造函数的事实,在.Net源代码中,构造函数List(IEnumerable<T> collection)检查传递的Enumerable是否为null,然后使用相反的方式将其强制转换为ICollection ICollection<T> c = collection as ICollection<T>.

在TypeScript中我这样做var c: ICollection<T> = collection(集合是一个IEnumerable<T>),但得到以下错误:

Cannot convert 'IEnumerable<T>' to 'ICollection<T>': Type 'IEnumerable<T>' is missing property 'Add' from type 'ICollection<T>'.

我目前的代码如下:

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) {
                    // NOTE: Capacity will be ignored is Collection is not null
                    //       This is because we don't appear to be able to overload ctors in TypeScript yet!
                    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;

                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有其他人尝试过与接口的共同/反差?如果是这样,你是怎么过的?

谢谢,

Fen*_*ton 5

您可以使用TypeScript中的类型断言来禁止警告:

var c: ICollection<T> = <ICollection<T>> collection;
Run Code Online (Sandbox Code Playgroud)

类型断言实际上不会转换值 - 在运行时,这些类型的注释或断言都不存在,因为它们都被删除了.运行时值完全不受类型断言的影响.

但这并没有解决你没有add方法的问题.

此外,null这里的测试值不太可能:

if (collection == null) {
Run Code Online (Sandbox Code Playgroud)

null通常只用于故意缺席的值,undefined例如,你更有可能遇到这些值.您可以使用简写来测试这两个:

if (!collection) {
Run Code Online (Sandbox Code Playgroud)

我知道你执行的是智力活动,所以这下绝对注释不适用 - 但谁都值得注意的是重建的事情就像列表和收集方法换的方法来复制.NET忽略了一点,打字稿(和JavaScript)是一种不同的语言.TypeScript程序中的所有数组都是通用的,因此以所有这些不同的方式将它们包装起来几乎没有什么好处 - 它们只会变成开销.但正如我所提到的,作为一种智力练习,这是有趣的东西.