TypeScript Feature: Lazy object initialization

omqzjyyz  于 6个月前  发布在  TypeScript
关注(0)|答案(1)|浏览(59)

搜索词

懒惰对象初始化

建议

引入能够懒惰地初始化对象并检查是否已初始化的能力。
我建议使用新关键字 lazyof(或其他名称),其功能如下:

  • 您可以将 Partial<T> 分配给 lazyof T
  • 只有类型为 T 的属性才能分配给 lazyof T
  • 编译器应跟踪分配给类型为 lazyof T 的变量的属性。
  • 每次引用类型为 lazyof T 的变量时,它应被视为其类型的后者(参见示例1和2)。
  • lazyof T 变量超出范围时,编译器应检查 T 的所有必需属性是否已设置。

用例

  1. 以这种方式初始化对象:
const obj = {};
obj.foo = 1;

在JS中很常见。如果有适当的类型检查就更好了。

  1. 从JS迁移到TS更容易。您无需将懒惰对象初始化转换为急切。
  2. 急切对象初始化并不总是最简单的方法,可能会使代码复杂化。
  3. 在构造函数/命名构造函数中检查对象是否正确初始化的能力(参见最后一个示例)。

示例

简单示例:

const obj: lazyof { [key: string]: any } = {};
obj.foo = 1;
const otherObj = obj; // otherObj implicit type is { foo: number }
obj.bar = 'a';
const otherObj2 = obj; // otherObj2 implicit type is { foo: number, bar: string }

隐式函数返回类型:

function initialize() {
  const obj: lazyof { [key: string]: any } = {};
  obj.foo = 1;
  obj.bar = 'a';
  return obj; // function initialize implicit return type is { foo: number, bar: string }
}

具有特定接口:

interface Obj {
  foo: number;
}
const obj: lazyof Obj = {};
obj.foo = 1;
obj.bar = 'a'; // error, property bar doesn't exists on Obj.

超出范围:

interface Obj {
  foo: number;
  bar: string;
}
function initialize(obj: lazyof Obj) {
  obj.foo = 1;.
  // error. obj variable goes out of scope, but { foo: number } is not assignable to Obj
}

检查对象示例是否已初始化:

class Obj {
  foo: number;
  bar: string;
  private constructor() {}
  static namedConstructor(): Obj {
    const self: lazyof Obj = new Obj;
    self.foo = 1;
    console.log(obj.bar); // // error, property bar doesn't exists on { foo: number }
    return self;
    // error. self variable goes out of scope, but { foo: number } is not assignable to Obj
  }
}

检查清单

我的建议满足以下准则:

  • 这不会对现有的TypeScript/JavaScript代码造成破坏性更改
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不根据表达式的类型生成不同的JS的情况下实现
  • 这不是运行时特性(例如库功能、带有JavaScript输出的非ECMAScript语法等)
  • 此功能将与 TypeScript's Design Goals 的其他部分保持一致。

相关问题