question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow Object.defineProperty() to definitely assign properties

See original GitHub issue

Suggestion

✅ Viability 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, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

⭐ Suggestion

It would be nice if Object.defineProperty() and Object.defineProperties() calls could be read via the constructor to definitely assign class properties.

📃 Motivating Example

https://www.typescriptlang.org/play?ssl=12&ssc=2&pln=1&pc=1#code/MYGwhgzhAEDiBOBTRAXR9oG8BQ0-QDswBbRALmghXgEsCBzAbl33qVTvoqtoef2jAA9gR4BXYCiHwAFEVLdqnAJRYWAvCgAWNCADp5iaAF5CJRPw14A8gCMAVokl6AJogBmdRAAV4QgA7oKACeMtq6ADTQAERsyCic0VE4Vlb0qDKqKak5SChi8ATQAAZaiCAgQtAAJJiGAL7F6jnQ9c0C9cqWeG31QA

class Greeter {
    name: string;
    greeting: string;
    constructor(name: string) {
        this.name = name;
        Object.defineProperty(this, "greeting", {
            get() {
                return `hello ${name}`
            }
        });
    }
}

Currently the greeting property in the class will cause the error Property 'greeting' has no initializer and is not definitely assigned in the constructor.

💻 Use Cases

This is not a big deal because we can use a “definite assignment assertion“ (!) after the greeting property identifier, but it would be nice for TypeScript to be aware of these defineProperty calls.

🔍 Search Terms

constructor, Object.defineProperty, Object.defineProperties, definitely assigned, strictPropertyInitialization, definite assignment operator Property has no initializer and is not definitely assigned in the constructor.

This is potentially a duplicate of the following issues:

Feel free to close as duplicate!

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:6
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
MichaelTheriotcommented, Jan 6, 2022

This suggestion only speaks of class properties but it would also be desirable for regular objects.

Consider this callable object with regular assignment:

image

This correctly produces:

const typeA: {
    (): number;
    x: number;
}

If I want x to be not configurable, not enumerable, and not writable then I have to use defineProperty:

image

But the x property is now missing on the type. I would expect instead to get:

const typeB: {
    (): number;
    readonly x: number;
}

I don’t know if there needs to be a separate issue created for supporting regular objects.

1reaction
ThaJaycommented, Mar 17, 2021

I run into the same problem with this much simpler code:

class Thing {
  someString: string;
  someNumber: number;

  constructor (data) {
    this.setData(data);
  }

  setData(data) {
    this.someString = data.someString;
    this.someNumber = data.someNumber;
  }
};

Now I can use ! or I can duplicate the logic inside of setData, but it seems a bit naive of the ts compiler to not follow a call to a function on this before it decides the code is noncompliant.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Object.defineProperty() - JavaScript - MDN Web Docs
This method allows a precise addition to or modification of a property on an object. Normal property addition through assignment creates ...
Read more >
JavaScript ES5: Meet the Object.defineProperty() Method
It is a method of ECMAScript 5, and it's used to define or override the attributes of an object. It accepts as a...
Read more >
A Brief Guide to the Object.defineProperty() Method in ...
It indicates whether the property value can be changed using the assignment operator (=). If not set, it defaults to false . If...
Read more >
Why does a property created with Object.defineProperty in ...
function Test() { return (target: object, key: string) => { let val = ''; Object.defineProperty(target, key, { get: () => val, set: (v:...
Read more >
Property flags and descriptors
defineProperty() (and Object.defineProperties()), all its descriptor flags are set to false by default. This is in contrast with when we define ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found