简体   繁体   English

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

[英]Is it possible to define a type-safe handle in TypeScript?

I'd like to be able to define a type-safe equivalent to a HANDLE or HWND in TypeScript. 我希望能够在TypeScript中定义与HANDLE或HWND等效的类型安全。 The use case is instantiating a concrete type which is provided to the user as an opaque type, who's only use is as input to other API functions. 用例正在实例化一个具体类型,该类型作为不透明类型提供给用户,用户只能将其用作其他API函数的输入。 Something like the following: 类似于以下内容:

 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
}

I've been encountering 2 issues: 我遇到了2个问题:

  1. You can't return an object of a type you haven't exported. 您不能返回未导出类型的对象。 This is why I'm returning the value as an empty interface type. 这就是为什么我将值作为空接口类型返回的原因。
  2. Any value implements the empty interface or empty class. 任何值都将实现空接口或空类。 This seems to make it impossible to create a type-safe opaque handle. 这似乎使得不可能创建类型安全的不透明句柄。

Has anyone done something like this before? 有人做过这样的事吗?

Why it is not an error 为什么不是错误

For 对于

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

Its not a compile error since TypeScript uses a structural type system instead of a nominal type system that you might be used to from C#/JAVA etc. 它不是编译错误,因为TypeScript使用结构类型系统而不是C#/ JAVA等中可能习惯的名义类型系统。

What this means is that two types are compatible if their members (structure) match up irrespective of the name (nominal). 这意味着如果类型( 名称 )匹配,则它们的成员 (结构)匹配,这两种类型是兼容的。 Eg the following is okay 例如以下没事

class Foo{}

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

But the following is not okay: 但是以下情况并不可行:

class Foo{
    bar:number;
}

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

To make it a compile error 使它成为编译错误

Just add some property unique to Handle that doesn't exist on invalid types. 只需添加一些对Handle唯一的属性,该属性在无效类型上不存在。 Eg I added the property value:number below which causes the compile error as expected: 例如,我在下面添加了属性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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM