microsoft / microsoft/TypeScript

The class is accessible from the field decorator expression when Babel and the Proposal Playground throw a ReferenceError

Open
#57,247 0 comments 0 reactions 1 assignee View on GitHub

@rbuckton is already working on this.

Since Feb 1, 2024.

Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔎 Search Terms

"decorator", "ReferenceError", "cannot access", "before initialization"

🕗 Version & Regression Information
  • Tested versions: 5.3.3 and Nightly
⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.0-dev.20240131&ssl=18&ssc=1&pln=29&pc=51#code/GYVwdgxgLglg9mABAJQKYHMYGcqoE4DCANgIZZYAUAUIogB7FlYA0NiA+hArnVFQJSIA3my5gscIqgB0ROOgoByNJhz5UAE0QRS5RIsQBqeo3L8A3FQC+VKqEiwEKDNlx4AYjFRENFBrqxBEVo8VCgQPCR7aHgkAEkwMHwVV3xPb182WnYANxIiEFRWWmyxHj5aIKztBAkpWXlqEpKAAxS1UK1gLx9EABIhTm5UXmkwEgBbGSg4AGUoPBgwBX4rRCXtAP6hfyYxydQrFuqLNitLGyoAeivEABUAC2x1rEQSRCwHuAB3CDJURBwYCIKAPAEaGDAYDqSAAigkMBaAAOeDgACMSGiiABPN6INEgdCCNFhb6oVBIUHg1BcPAkGZ4V7XW5cCZImCkRxIIH3bFI1CzCCLJFQN6IxAAIUx3iuACsSHksEKYCKNDS4HSGVhpBr0NJmczEAB1MGUsGbJiINW0+kaxAAAXablMr2eJCRSKIXg0rBubyIRBB5u6GSt6s1GtejpcHXSPgoAEE8LAdKhBKg8gV6QDvjBQXAQKL8KjGb7blSLXokympC83hAIKhyDAsQDgKiJkHqTaGYgRiim1hYvq-RLC+tgdiCzUJlMwKKC6KK9HVM6tlTuQ2Iq8EX28CXEAAiAgIsBwUUkBuD-TVmCpgwk4AagFLPMwfIwABe9Nih5HV0NKUSUDCgABklgAa0QXNQRqNUAC5EAeKAoCRLB4JuDFgNlbV4CuUJPQAYgAfjRVFviwfAsAAXjVYASBAIgoCwABSAAmAh2IABjPKBuK8biAEZBPYzi2J489+NQdgJnRITBIAMgJDkNGopSQA5KAEho+iiEohTaVQHDqIAZmkNjFKwfkIGo3T9LkOBKNs-J9K4NV2CIT9qIAcQATQANW+DR0DodBQPQIh0AATgmBMJQTAApABFABpXyAAkAFlfO8iAAEc4AAUQAFgAEQIBMADl0DiAAtWrfITABVZq4nkCUAHZ3CIRquMqmAEwAWgeJMwH89wkoS2Y4gTEyJmxABWdAlTiPL0AlLjkAAeS29A4AlbFKoSh5PwWlrCq4pLkFmBbkDiLAkolPLUDgEzQIADlmiaCEG-yUrywqYG+QqUtKyqiDoYqE182V3GQQrKvcCU8DyugJUK-y4He-yCHQJKAAUCGQDqSHS9AIITQqIO+TL0u+fz-JMuh8bRQT3rYo0wEayq6DiGBCrho0jXmuh0tlBaSDiFLPygeKIKRI0AA0iABpEUoTBM6FmQSmpSwSwroKLCriuIHjuCYzsViZqcK9a0W82Z0Ch7ymrgfGJXQb4JUV4q8GQAhFagBN8YANgeYBsV8uhsQ0JKPBAPLQP6qBQO8qcNcVkgTKa7Fvjy9LZlq43CsK96jQlHXfLuXysW+DqeO+JrKuK4AUrud7+u+FKJVmWZvnYI0FqRdK8sG3zCu+O4lrYh4iH8j3QaSwTvMEiVfPQEgJW+fHmtK5B-NquAE1QJKE2QdAk380qkpIZBMu80q4Ey5r1YTAg2O+T9CqSo0L-xzyHjuFqncPASU0SlXXgmBSaoCToGcnpVACknx4EbAmAMICERYGQRMHSLlEGyQ0IxJs8D9KfBVPyDQ+NURIkci5EhiCIAwBQVIRhaAaFqQzPkEA2Z6FII5AKL8qBeGwCmBgnI3heESAiI2O4fIhEEKIQpL0SQjR0iRNRBYhQFIDkosxaiFIciiVCJePiHEcAkHQKgQabFtGhBQl4PAwiSB4EsXohS4jGSxGoh1cyZkooKRGG4cYRB-6EiWDRBSTAQBsi5DRFiHUJTxNKvwQ0CItAVlKuGW0jJEBULgDQrA+RcmkGxOgVE4AtAUGQqhdCNx5SKmVKqLJWodQuKuIIUE5E8RoGhKEWEhV9x2g2Gic8DxtD-BYIaM8iAJjZjwF2SsrxrQamyXWd0npvSAnmbxfUK5UiEACFQHQlpbypmEGwPZsYei+FOVIFJtBYBQCkJYC5To0jXMTMmO8dzRDDHnC82gYgcB4BANADUFANBVGaFtNEsoaRQGkEwGA6AwAUFBNgZgVpEAAB9sXCCsKcWgNgbBAA

💻 Code
function RegisterClass(
  xClass,
  _context
) {
  console.log('Registered class ' + xClass);
}

function RegisterField(xClass) {
  return function InnerRegisterField(
    _value,
    _context
  ) {
    console.log(
      `Registered field ${_context.name.toString()} in class ${xClass.name}`
    );
  };
}

// This is a showcase of the difference (and probably a bug) between the decorators 
// compilation of TypeScript and Babel/javascriptdecorators.org.
//
// When the class decorator @RegisterClass is applied,
// all the field decorators @RegisterField(Article) evaluate without errors and
// the class is accessible from the decorator expression.
// But if you comment out the @RegisterClass then at the runtime there is an error "Cannot access 'Article' before initialization".
// Babel (https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=GYVwdgxgLglg9mABAJQKYHMYGcqoE4DCANgIZZYAUAUIogB7FlYA0NiA-hArnVFQJSIA3my5gscIqgB0ROOgoByNJhz5UAE0QRS5RIsQBqeo3L8A3FQC-VKqEiwEKDNlx4AYjFRENFBrqxBEVo8VCgQPCR7aHgkAEkwMHwVV3xPb182WnYANxIiEFRWWmyxHj5aIKztBAkpWXlqEpKAAxS1UK1gLx9EABIhTm5UXmkwEgBbGSg4AGUoPBgwBX4rRCXtAP6hfyYxydQrFuqLNitLGyoAAXa3UywqHSZEAEE8WB1UYTYblw70nwUN4fKT8NiwKBSSw_W5pHq-YEwT5g2hlVBgKDQ1G1BYgaBwPAUDRVZoAeQARgArVDQaRMGDoMAUKAAC2wzEQWgAPlzhFZTrQbDYgA&debug=false&forceAllTransforms=false&modules=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2&prettier=false&targets=&version=7.23.9&externalPlugins=&assumptions=%7B%7D)
// and the Decorators Proposal Playground (https://javascriptdecorators.org/) throw a ReferenceError in both cases,
// no mater you apply the class decorator or not.
@RegisterClass
class Article {
  @RegisterField(Article)
  title;

  @RegisterField(Article)
  content;

  constructor(d) {
    Object.assign(this, d || {});
  }
}

🙁 Actual behavior

A ReferenceError is thrown only when you do not apply the class decorator, otherwise the class is accessible. That differs from Babel and https://javascriptdecorators.org/

🙂 Expected behavior

There should be a ReferenceError when trying to access the class from the field decorator expression, no matter if you have class decorator applied or not.

Additional information about the issue

This is a showcase of the difference (and probably a bug) between the decorators
compilation of TypeScript and Babel/javascriptdecorators.org.

When the class decorator @RegisterClass is applied,
all the field decorators @RegisterField(Article) evaluate without errors,
the class Article is accessible from the decorator expression.
But if you comment out the @RegisterClass then occurs an error "Cannot access 'Article' before initialization".

Babel (Link with code: https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=GYVwdgxgLglg9mABAJQKYHMYGcqoE4DCANgIZZYAUAUIogB7FlYA0NiA-hArnVFQJSIA3my5gscIqgB0ROOgoByNJhz5UAE0QRS5RIsQBqeo3L8A3FQC-VKqEiwEKDNlx4AYjFRENFBrqxBEVo8VCgQPCR7aHgkAEkwMHwVV3xPb182WnYANxIiEFRWWmyxHj5aIKztBAkpWXlqEpKAAxS1UK1gLx9EABIhTm5UXmkwEgBbGSg4AGUoPBgwBX4rRCXtAP6hfyYxydQrFuqLNitLGyoAAXa3UywqHSZEAEE8WB1UYTYblw70nwUN4fKT8NiwKBSSw_W5pHq-YEwT5g2hlVBgKDQ1G1BYgaBwPAUDRVZoAeQARgArVDQaRMGDoMAUKAAC2wzEQWgAPlzhFZTrQbDYgA&debug=false&forceAllTransforms=false&modules=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2&prettier=false&targets=&version=7.23.9&externalPlugins=&assumptions=%7B%7D)
and the Decorators Proposal Playground (https://javascriptdecorators.org/) throw a ReferenceError in both cases,
no mater the class decorator is applied or not.

This looks like a bug and leads to confusion, because the code you wrote once worked, but suddenly throws a ReferenceErrors only because you decided to removed the class decorator. And also i think that TypeScript should throw a compile time error when we try to access the class when it's not initialized.

Thanks a lot! Hope i provided enough details.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.