programing

타입스크립트에 롬복과 같은 것이 있습니까?

minimums 2023. 6. 7. 22:26
반응형

타입스크립트에 롬복과 같은 것이 있습니까?

NodeJS 백엔드의 상용어구 코드를 줄일 방법을 찾고 있습니다.예를 들어 Lombok에서는 객체에 대한 주석을 통해 생성자를 주입하고 getter/setter를 주입할 가능성이 있습니다.

TypeScript에서 이것을 할 수 있는 방법이 있습니까?

저는 그것을 빠르게 검색했고 Lombok과 같은 기능을 TypeScript에 가져오려고 시도하는 이런 프로젝트를 발견했습니다. 하지만 보시다시피, 그 프로젝트는 드물고 널리 사용되지 않습니다.이는 다음과 같은 질문을 의미합니다.왜 그런 도구를 원합니까?

TS는 이미 보일러 플레이트를 줄이는 데 꽤 능숙합니다.클래스를 정의할 때 일반적으로 다음과 같이 수행합니다.

class A {
  constructor(private fieldA: string, private readonly fieldB = 0) {}
}

이것은 꽤 간결하죠, 그렇죠?당신은 TS의 기능과 자바의 기능을 비교하고 있는 것 같습니다.자바는 매우 말이 많고 롬복은 그것을 크게 돕습니다.그러나 TS와 JS는 다르고, 롬복이 해결하는 일부 문제는 TS가 이미 해결하고 있지만, 다른 문제는 TS와 JS의 세계에서 문제가 되지 않습니다.

무엇보다도, 위의 구문은 접근 수식자가 있는 특정 유형의 클래스 필드를 생성하고 당신은 또한 발견할 수 있습니다.readonly에 있키드워는 fieldB 및 기 값0은 실행 시 됩니다( this.fieldA = fieldA을 포함하고 있습니다. 그래서 이것은 이미 롬복의 건설자를 주입하는 능력 이상을 포함하고 있습니다.: 할 수 . 오버로드를 JS(따라서 TS에서는)에서는 단일 생성자만 가질 수 있습니다. JS는 메서드 오버로드를 지원하지 않습니다.

이제 게터/세터에 대해서는 JS(또는 TS)에서 Java와 동일한 방식으로 사용되지 않습니다.JS에서는 필드를 직접 사용하는 것이 일반적이며, 세터와 게터는 다음과 같은 특수한 경우에만 사용됩니다.

  1. 게터만 정의하여 런타임에 개체 속성에 값을 설정하는 것을 금지합니다.일반적으로 이것은 약간 오버킬입니다. TS를 사용하기 때문에 필드를 다음과 같이 선언할 수 있습니다.readonly컴파일러는 사용자가 해당 속성에 할당하지 않도록 합니다. getter를 사용할 필요가 없습니다.컴파일 시간 확인 없이 JS에서 개발하는 경우, 규칙은 비공개 속성(수정해서는 안 되는 속성)을 밑줄로 표시하는 것입니다.어느 쪽이든 수정하면 안 되는 변수를 수정할 수 있지만 Java와 달리 이는 JS(및 TS)의 모든 곳에서 get/set을 사용하기에 충분한 이유로 간주되지 않습니다.대신 런타임에서 수정이 발생하지 않는지 확인해야 할 경우 세터 없이 위에서 언급한 게터를 사용하거나 개체의 속성을 쓰기 불가능으로 구성합니다.
  2. 설정/취득 기능에 사용자 정의 논리가 있는 것도 이러한 논리를 사용하는 좋은 이유입니다.일반적인 사용 사례는 여러 변수로 계산되지만 개체의 필드처럼 보이도록 하는 게터입니다.때 JS를 사용하지 않기 때문입니다.() 논리.이 논리는 사용자 정의이므로 주석만으로 생성할 수 없습니다.

보시다시피, Java에서 Lombok이 처리하는 일부 문제는 TS에서 이미 처리되고 다른 문제는 문제가 되지 않습니다.


5-9-2021 편집 - @Reijo의 질문에 대한 답변: Lomboks 기능은 게터/세터/생성자 이상입니다.@Builder Annotation을 보면서, 저는 당신이 이것에 대해 어떻게 말할지 관심이 있습니다.

Lombok for Java와 동일한 유틸리티 모음을 제공하는 TypeScript/JavaScript 라이브러리가 있는지 여부에 대한 질문이라면 제가 알기로는 NO입니다.저는 부분적으로 TypeScript가 즉시 제공하는 기능 때문이라고 생각합니다(위에서 이미 개요를 설명했듯이). 이것은 Java가 TypeScript나 Groovy와 같은 언어보다 Lombok을 더 필요로 한다는 점을 다시 깨닫게 합니다.빌더 패턴과 같이 TS가 제공하지 않는 것이 필요할 때는 빌더 패턴(코어에서 JS Proxy 사용)이나 JS(그리고 사실상 TS)의 유연한 특성 덕분에 특정 문제를 해결하는 라이브러리를 사용하여 쉽게 작성할 수 있습니다.

이 모든 것은 좋지만, 롬복이 하는 것처럼 주석(TS 세계에서는 장식자라고 하며 다르게 작동함)을 통해 좀 더 선언적인 방식으로 기능을 추가하고 싶을 것입니다.복잡할 수도 있습니다.

우선 TS에서 데코레이터를 통해 타입을 수정하면 TS 컴파일러는 변경 내용을 인식하지 못합니다.예를 들어 장식가에 메소드를 추가하면 TS는 새로운 메소드를 인식하지 못합니다.자세한 내용은 이 토론을 참조하십시오.

즉, 장식자를 포기하고 대신 기능을 사용하여 유형을 수정하거나(가능한) AST로 이동합니다.그게 롬복이 작동하는 방식입니다.주석 처리라고 하는 컴파일 단계에서 주석이 달린 유형을 사용하며 javac(및 Eclipse 컴파일러)의 해킹으로 인해 AST를 수정합니다(예: 주어진 클래스에 대한 내부 작성기를 만듭니다).TS/JS와 비슷한 방식으로 작업을 수행할 수 있습니다.

TS나 JS에서 주석을 처리하는 것과 같은 것은 없지만 소스 코드를 취하고 목표를 달성하기 위해 AST를 수정하는 빌드 단계를 만들 수 있습니다(바벨도 그렇게 작동합니다).이로 인해 클래스에 메소드를 추가하거나, 광범위한 의미에서 사용된 주석(반드시 장식자는 아님)을 기반으로 작성자 등을 생성할 수 있습니다.

하지만 이 접근 방식은 어려운 과제입니다.AST가 고급 주제인 것 외에도, 비록 여러분이 그것을 작동시키더라도, 여러분은 IDE의 지원이 필요할 것이고, 이것은 오늘날 또한 언어 서버의 지원을 의미합니다.그리고 그것은 심장이 약한 사람들을 위한 것이 아닙니다.

하지만 TS/JS 세계에서 보고 싶어하는 사람들이 꽤 있는 것처럼 보이기 때문에 TS용 롬복과 같은 것을 만들 계획이라면 내 편집은 누군가를 겁주지 않을 것입니다.앞에 놓여 있는 것만 표시해야 합니다 ;).

저는 @Getters와 @Setters Lombok 장식가들의 대안을 찾았습니다.

사용해 보십시오.

import { capitalize } from "lodash";

const Getters = () => <T extends {new(...args:any[]):{}}>(constructor:T) => {
  return class extends constructor {
    constructor(...args: any[]) {
      super(...args);
      const props = Reflect.ownKeys(this);
      props.forEach((prop: string) => {
        const capitalizedKey = capitalize(prop);
        const methodName = `get${capitalizedKey}`;
        Object.defineProperty(this, methodName, { value: () => this[prop] });
      });
    }
  }
}
const Setters = () => <T extends {new(...args:any[]):{}}>(constructor:T) => {
  return class extends constructor {
    constructor(...args: any[]) {
      super(...args);
      const props = Reflect.ownKeys(this);
      props.forEach((prop: string) => {
        const capitalizedKey = capitalize(prop);
        const methodName = `set${capitalizedKey}`;
        Object.defineProperty(this, methodName, { value: (newValue: any) => { this[prop] = newValue } });
      });
    }
  }
}

@Getters()
@Setters()
export class Person {
  [x: string]: any;
  nom: string;
  prenom: string;

  constructor(nom: string, prenom: string) {
    this.nom = nom;
    this.prenom = prenom;
  }
}

언급URL : https://stackoverflow.com/questions/59136271/is-there-something-like-lombok-for-typescript

반응형