Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassDeclaration::set() can't take instances of a class structure with getters among the methods safely #1527

Open
ajvincent opened this issue Apr 15, 2024 · 1 comment

Comments

@ajvincent
Copy link
Contributor

Describe the bug

Version: 22.0.0

To Reproduce

import { Project } from "ts-morph";

const project = new Project();
const sourceFile = project.createSourceFile("test.ts", ``);

const classDecl: ClassDeclaration = sourceFile.addClass({ name: "MyClass" });

const outerStructure: ClassDeclarationStructure = {
  kind: StructureKind.Class,
  name: "MyClass",

  methods: [],
};
// ...

class FourthMethod implements MethodDeclarationStructure {
  kind: StructureKind.Method = StructureKind.Method;
  #name = "fourthMethod";
  get name(): string {
    return this.#name;
  }
  set name(newName: string) {
    this.#name = newName;
  }
}
outerStructure.methods?.push(new FourthMethod);

classDecl.set(outerStructure);
console.log(classDecl.print());

Expected behavior

class MyClass {
    fourthMethod {
    }
}

Actual Behavior

ManipulationError: Manipulation error: A syntax error was inserted.

module.ts:11:5 - error TS1068: Unexpected token. A constructor, method, accessor, or property was expected.

Analysis

I tracked this down to a single line in ClassLikeDeclarationBase.ts, in the insertMethods() method:

structures = structures.map(s => ({ ...s }));

Frankly, I don't understand the point of this line. The spread operator, however, will not enumerate over inherited properties (such as the name getter in my sample class above).

Commenting out this line, every existing test in ts-morph still passes. I assume the line itself is a protection against something... but what?

@ajvincent ajvincent changed the title ClassDeclaration::set() can't take instances of a class with getters safely ClassDeclaration::set() can't take instances of a class structure with getters among the methods safely Apr 15, 2024
@dsherret
Copy link
Owner

Without seeing the code, my guess is a naive attempt at cloning in order to not modify the objects the user passed in. Not sure if that actually occurs there though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants