简体   繁体   中英

How can I narrow the type of a readonly property of a derived class?

I want to extend Uint8Array such with a class that constrains the type to a certain length. For example:

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

However, when I try to instantiate that class I get an error because the length property on Uint8Array only has a getter:

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

If I don't do the assignment in the class declaration and instead only do length: 32 then I get a compiler error saying that length is never assigned.

Is there any way I can tell TypeScript (either via assertion of via proof) that the length property of this class will always be 32 and thus its type should be narrowed to 32 from number ?

I specifically want the compiler to know about the narrowing so I can have a function with a signature like:

function apple(data: ArrayLike<number> & { length: 32 })

Such a signature would enhance type checking in my project, without tightly coupling to any specific array of numbers container. The only requirement is that the thing they give me must (provably by the compiler) have exactly 32 elements.

As you simply wish to refine the type of the length member, specifically from number to 32 , and are only initializing it to satisfy type checking and thereby introducing a runtime error, we can resolve the issue by leveraging Declaration Merging .

Specifically we can refine the typeof of length to 32 by introducing an interface which declares the property and merges with the class itself.

The following does the trick

interface Bytes32 {
  readonly length: 32;
}

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

This technique has a broad range of applications but also needs to be used with care.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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