免责声明:这可能是一个膝跳帖子。 打字稿新手警报!也有点咆哮
我只是在Typescript+Node上下文中尝试YDKJS系列书籍中的OLOO方法。
// what I'd like to write - valid JS
let Account = {
get id(){
return this._id;
},
get name(){
return this._name;
},
init(id, name){
this._id = id;
this._name = name;
}
}
let TypedAccount = {
identify(){
console.log(`This is ${this.name}'s ${this._type} account`);
},
init_L2(type){ // avoid collision with base#init
this._type = type;
}
}
Object.setPrototypeOf(TypedAccount, Account);
function createAccount(id, name, type){
let instance = Object.create(TypedAccount);
instance.init(id, name);
instance.init_L2(type);
return instance;
}
let o1 = createAccount(101, 'Tom', 'Savings'),
o2 = createAccount(102, 'Jerry', 'Current');
console.log (o1.identify());
console.log (o2.identify());
OLOO的主要吸引力在于它的简单性。但是我不得不通过编写更多代码来帮助/安抚 Typescript 编译器;我不必使用基于类的方法编写的代码。
- 对于像 Account 这样的每种类型,我需要声明一个匹配的接口 IAccount,以便可以检查/自动完成客户端使用情况。我可以通过使用任何逃生路线来作弊。
- TS 会抱怨未声明字段的使用,所以我需要定义所有字段及其类型,然后再使用this.field访问它们。没有太多的努力,但仍然。例如_id:默认值;
- 在对象文本中指定类型信息。如果一个对象有一个映射[字符串=>数字],我使用嵌套对象。但是,TS 想知道密钥的类型和值。所以我需要创建一个界面来装饰字段
interface IMapStringsToNumbers {
[ key: string ]: number;
}
//
let Account = {
_holdings : <IMapStringsToNumbers> {}
也许最后 2 个与 OLOO 无关。有没有更简单的方法?
当你在 TypeScript 中执行class Account
时,你会同时创建两件事:
- 编译类型的实体
Account
它是 Account 类的实例类型 - 一个运行时实体(变量(,
Account
它是类本身(== Javascript中的构造函数(
有了所有必要的连接,即已经知道new Account
变量返回Account
类型的东西。
当你做let Account = ...
你只创建一个变量,并留下你自己的类型。Typescript 无法(也可能永远不会(跟踪您的原型分配并推断Account
和TypedAccount
以某种方式相关。
在主观上,我不会称"简单"为需要你编写的模式
init_L2(type){ // avoid collision with base#init
或
Object.setPrototypeOf(TypedAccount, Account)
底线:不要那样做。使用类。