是否可以在TypeScript中定义类型安全句柄?

时间:2014-06-30 00:05:40

标签: typescript

我希望能够在TypeScript中定义类型安全等效于HANDLE或HWND。该用例是实例化一种具体类型,该类型作为不透明类型提供给用户,其仅用作其他API函数的输入。如下所示:

 module foo {

    export
        class Handle<T> {
    }

    class Property extends Handle<Property>
    {
        constructor(public value = 12) { super(); }

    }

    export interface IProperty { }

    export function makeProperty(): Handle<IProperty> {
        return new Property();
    }

    export function getPropertyValue(p: Handle<IProperty>) {
        return (<Property>p).value;
    }

}


module bar {
    var s = foo.makeProperty();
    var p = foo.getPropertyValue(12); // this should be a compile error
}

我遇到了两个问题:

  1. 您无法返回您尚未导出的类型的对象。这就是我将值作为空接口类型返回的原因。
  2. 任何值都实现空接口或空类。这似乎使得无法创建类型安全的不透明手柄。
  3. 以前有人做过这样的事吗?

1 个答案:

答案 0 :(得分:1)

为什么不是错误

对于

var p = foo.getPropertyValue(12); // this should be a compile error

它不是编译错误,因为TypeScript使用结构类型系统而不是名义类型系统,您可能习惯使用C#/ JAVA等。

这意味着如果两个类型的成员(结构)匹配,则无论名称(名义)如何,两种类型都是兼容的。例如。以下是好的

class Foo{}

var foo:Foo = 123; // okay since number contains everything that a Foo needs (which is nothing)

但以下情况并不合适:

class Foo{
    bar:number;
}

var foo:Foo = 123; // Error NOT okay since number doesn't contain member bar

使其成为编译错误

只需在Handle添加一些对无效类型不存在的属性。例如。我在下面添加了属性value:number,这会导致编译错误:

module foo {

    export class Handle<T> {
        constructor(public value:number){}
    }

    class Property extends Handle<Property>
    {
        constructor(public value = 12) { super(value); }

    }

    export interface IProperty { }

    export function makeProperty(): Handle<IProperty> {
        return new Property();
    }

    export function getPropertyValue(p: Handle<IProperty>) {
        return (<Property>p).value;
    }

}


module bar {
    var s = foo.makeProperty();
    var p = foo.getPropertyValue(12); // Compile Error
}