microsoft / microsoft/TypeScript
Feature: Lazy object initialization
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
Search Terms
lazy object initialization
Suggestion
Introduce ability to initialize objects lazily and check if it was initialized.
I suggest new keyword lazyof (or other name) which would work as following:
- You can assign
Partial<T>tolazyof T. - Only property from type
Tcan be assigned tolazyof T. - Compiler should keep track of what properties were assigned to variable of type
lazyof T. - Every time you reference variable with type
lazyof Tit should be treated as if it's type was{ properties, which, you, assigned, up, to, this, point }. This implies that when you assign such variable to other variable/return it, the implicit type should be latter (see example 1 and 2). - When
lazyof Tvariable goes out of scope, compiler should check if all the required properties ofTare set.
Use Cases
- Initializing objects like this:
const obj = {};
obj.foo = 1;
is common practice in JS. It would be nice to have a proper type checking
-
Easier migration from JS to TS. You don't need to convert lazy object initialization to eager.
-
Eager object initialization is not always the simplest approach and might complicate code
-
Ability to check whether object was properly initialized in constructor/named constructor (see last example)
Examples
Simple example:
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 }
Implicit function return type:
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 }
}
With specific interface:
interface Obj {
foo: number;
}
const obj: lazyof Obj = {};
obj.foo = 1;
obj.bar = 'a'; // error, property bar doesn't exists on Obj.
Going out of scope:
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
}
Check if object instance is initialized:
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
}
}
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the TypeScript compiler and type-checking design relevant to variable assignment, property tracking, inferred types, and scope checks; the issue names no specific files or tests. Done means defining and implementing the proposed lazyof behavior, including assignment restrictions, evolving inferred types, property access errors, and validation when a variable leaves scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100