typescript - 如何在 TypeScript 中使用静态方法和构造函数签名声明接口?
问题描述
我有两个具有通用静态方法的类。添加包括静态方法实现和构造函数签名的通用接口的最佳方法是什么?
我为相应的区块链编写了实现钱包逻辑的类BitcoinHDWallet
。EthereumHDWallet
我想添加一个通用接口HDWallet
来描述与它们一起工作的逻辑,以便用户可以执行以下操作:
const multiWallet: Array<HDWallet> = [];
multiWallet[0] = new BitcoinHDWallet(...);
multiWallet[1] = new EthereumHDWallet(...);
这两个类共享一些常见的静态方法。
0)如果我用abstract class
它来描述接口,我不知道如何添加构造函数签名。
1)如果我使用interface
,我不能添加静态方法实现。
理想情况下,我想做这样的事情:
abstract class HDWallet {
/**
* Return new random mnemonic seed phrase
*/
static generateMnemonic(): string {
return Bip39.generateMnemonic();
}
constructor(bip39SeedPhrase: string, password?: string, testnet?: boolean);
abstract getAddress(addressIndex?: number) : string;
abstract async getBalance(address? : string) : Promise<number>;
...
}
class BitcoinHDWallet extends HDWallet {...}
class EthereumHDWallet extends HDWallet {...}
解决方案
没有开箱即用的方法。抽象类是最接近您想要的东西,但它确实不允许您检查该类型是否具有特定的构造函数。
一种方法是向类添加一个额外的类型参数。这可以被限制在typeof HDWallet
哪个将代表基类的构造函数签名。派生类必须将自己作为此额外参数传递,然后将检查其构造函数签名以与基类签名兼容:
abstract class HDWallet<T extends typeof HDWallet> {
/**
* Return BIP39 12 words new random mnemonic seed phrase
*/
static generateMnemonic(): string {
return "";
}
constructor(bip39SeedPhrase: string, password?: string, testnet?: boolean) { }
abstract getAddress(addressIndex?: number) : string;
abstract async getBalance(address? : string) : Promise<number>;
}
class BitcoinHDWallet extends HDWallet<typeof BitcoinHDWallet> {
getAddress(addressIndex?: number) : string { return ""}
async getBalance(address?: string): Promise<number> { return Promise.resolve(0);}
}
class EthereumHDWallet extends HDWallet<typeof EthereumHDWallet> { /// error
constructor(testnet?: boolean) {
super("", "", false)
}
getAddress(addressIndex?: number) : string { return ""}
async getBalance(address?: string): Promise<number> { return Promise.resolve(0);}
}
注意使用接口,您可以描述类的静态部分以及实例类型,这取决于您要验证的内容:
interface HDWalletClass {
generateMnemonic(): string
new (bip39SeedPhrase: string, password?: string, testnet?: boolean): {
getAddress(addressIndex?: number): string;
getBalance(address?: string): Promise<number>;
}
}
abstract class HDWallet {
/**
* Return BIP39 12 words new random mnemonic seed phrase
*/
static generateMnemonic(): string {
return "";
}
constructor(bip39SeedPhrase: string, password?: string, testnet?: boolean) { }
abstract getAddress(addressIndex?: number) : string;
abstract async getBalance(address? : string) : Promise<number>;
}
class BitcoinHDWallet extends HDWallet {
getAddress(addressIndex?: number) : string { return ""}
async getBalance(address?: string): Promise<number> { return Promise.resolve(0);}
}
class EthereumHDWallet extends HDWallet { /// error
constructor(testnet?: boolean) {
super("", "", false)
}
getAddress(addressIndex?: number) : string { return ""}
async getBalance(address?: string): Promise<number> { return Promise.resolve(0);}
}
let a: HDWalletClass = BitcoinHDWallet; //ok
let b: HDWalletClass = EthereumHDWallet; // err
推荐阅读
- typescript - 如何使用 Typescript 定义 Google Cloud 函数?
- python - Python中的RSA解密如何获得字节数组?
- oop - DDD 中聚合的存储库之间的关系
- ios - 添加第二个和第三个文本字段。只能添加第一个和最后一个
- java - stdout 运行时错误无响应 ~ HackerRank 问题
- python - 卡在python代码中进行加密。错误是“str”类型对象的未知格式代码“x”
- ios - 将最后两个小时分成 10 分钟切片
- sql - 在正确的位置添加 CASE 表达式?
- php - 显示数组而不是图像的电子邮件
- crystal-reports - 获取特定字符串中的字符串