如何缩小派生类的只读属性的类型?

时间:2019-06-22 14:42:35

标签: typescript typescript-generics

我想扩展Uint8Array这样的类,以将类型限制为一定的长度。例如:

class Bytes32 extends ByteArray {
    constructor() { super(32) }
    length: 32 = 32
}

但是,当我尝试实例化该类时,由于在length上的Uint8Array属性只有一个吸气剂,所以我得到了一个错误:

TypeError: Cannot set property length of [object Object] which has only a getter

如果我没有在类声明中进行赋值,而是只做length: 32,则会收到编译器错误,指出从未length被赋值。

有什么方法可以(通过断言证明)告诉TypeScript此类的length属性将始终为32,因此其类型应为32number缩小到function apple(data: ArrayLike<number> & { length: 32 })

我特别希望编译器知道缩小的范围,因此我可以使用带有如下签名的函数:

public class testabb {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        testabb t = new testabb();
        t.login();
    }

    public static void login() {
        System.out.println("Login");    
    }
}

这样的签名将增强我项目中的类型检查,而无需紧密耦合到任何特定的数字容器数组。唯一的要求是,它们给我的东西必须(由编译器证明)必须具有32个元素。

1 个答案:

答案 0 :(得分:2)

您只是希望优化length成员的类型,特别是从number32,并仅对其进行初始化以满足类型检查的要求,从而引入运行时错误,我们可以利用Declaration Merging解决问题。

具体来说,我们可以通过引入一个声明属性并与类本身合并的接口来将length的类型细化为32

以下是技巧

interface Bytes32 {
  readonly length: 32;
}

class Bytes32 extends Uint8Array {
  constructor() { super(32); }
}

该技术具有广泛的应用范围,但也需要谨慎使用。