为什么凯尔·辛普森(Kyle Simpson)的OLOO方法感觉像是与Typescript潮流背道而驰?



免责声明:这可能是一个膝跳帖子。 打字稿新手警报!也有点咆哮

我只是在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 编译器;我不必使用基于类的方法编写的代码。

  1. 对于像 Account 这样的每种类型,我需要声明一个匹配的接口 IAccount,以便可以检查/自动完成客户端使用情况。我可以通过使用任何逃生路线来作弊。
  2. TS 会抱怨未声明字段的使用,所以我需要定义所有字段及其类型,然后再使用this.field访问它们。没有太多的努力,但仍然。例如_id:默认值;
  3. 在对象文本中指定类型信息。如果一个对象有一个映射[字符串=>数字],我使用嵌套对象。但是,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 无法(也可能永远不会(跟踪您的原型分配并推断AccountTypedAccount以某种方式相关。

在主观上,我不会称"简单"为需要你编写的模式

init_L2(type){  // avoid collision with base#init

Object.setPrototypeOf(TypedAccount, Account)

底线:不要那样做。使用类。

相关内容

最新更新