如何缩小派生 class 的只读 属性 的类型?
How can I narrow the type of a readonly property of a derived class?
我想扩展 Uint8Array
这样的 class 将类型限制在一定长度。例如:
class Bytes32 extends ByteArray {
constructor() { super(32) }
length: 32 = 32
}
但是,当我尝试实例化 class 时出现错误,因为 Uint8Array
上的 length
属性 只有 getter:
TypeError: Cannot set property length of [object Object] which has only a getter
如果我不在 class 声明中进行赋值,而只进行 length: 32
,那么我会收到一个编译器错误,指出 length
从未被赋值。
有什么方法可以告诉 TypeScript(通过断言或通过证明)这个 class 的 length
属性 将 总是 是 32
因此它的类型应该从 number
?
缩小到 32
我特别希望编译器知道缩小,这样我就可以拥有一个带有如下签名的函数:
function apple(data: ArrayLike<number> & { length: 32 })
这样的签名将增强我项目中的类型检查,而无需与任何特定的数字容器数组紧密耦合。唯一的要求是他们给我的东西必须(由编译器证明)恰好有 32 个元素。
因为您只是希望细化 length
成员的类型,特别是从 number
到 32
,并且只是对其进行初始化以满足类型检查,从而引入运行时错误,我们可以利用 Declaration Merging.
解决问题
具体来说,我们可以通过引入一个声明 属性 并与 class 本身合并的接口来将 length
的类型细化为 32
。
下面的技巧
interface Bytes32 {
readonly length: 32;
}
class Bytes32 extends Uint8Array {
constructor() { super(32); }
}
这项技术的应用范围很广,但也需要谨慎使用。
我想扩展 Uint8Array
这样的 class 将类型限制在一定长度。例如:
class Bytes32 extends ByteArray {
constructor() { super(32) }
length: 32 = 32
}
但是,当我尝试实例化 class 时出现错误,因为 Uint8Array
上的 length
属性 只有 getter:
TypeError: Cannot set property length of [object Object] which has only a getter
如果我不在 class 声明中进行赋值,而只进行 length: 32
,那么我会收到一个编译器错误,指出 length
从未被赋值。
有什么方法可以告诉 TypeScript(通过断言或通过证明)这个 class 的 length
属性 将 总是 是 32
因此它的类型应该从 number
?
32
我特别希望编译器知道缩小,这样我就可以拥有一个带有如下签名的函数:
function apple(data: ArrayLike<number> & { length: 32 })
这样的签名将增强我项目中的类型检查,而无需与任何特定的数字容器数组紧密耦合。唯一的要求是他们给我的东西必须(由编译器证明)恰好有 32 个元素。
因为您只是希望细化 length
成员的类型,特别是从 number
到 32
,并且只是对其进行初始化以满足类型检查,从而引入运行时错误,我们可以利用 Declaration Merging.
具体来说,我们可以通过引入一个声明 属性 并与 class 本身合并的接口来将 length
的类型细化为 32
。
下面的技巧
interface Bytes32 {
readonly length: 32;
}
class Bytes32 extends Uint8Array {
constructor() { super(32); }
}
这项技术的应用范围很广,但也需要谨慎使用。