문제

TypeScript 언어에서 메소드 오버로딩을 수행하는 방법이 있습니까?

나는 다음과 같은 것을 달성하고 싶습니다 :

class TestClass {
    someMethod(stringParameter: string): void {
        alert("Variant #1: stringParameter = " + stringParameter);
    }

    someMethod(numberParameter: number, stringParameter: string): void {
        alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
    }
}

var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");

다음은 내가 하고 싶지 않은 일의 예입니다(JS에서 해킹 오버로드의 해당 부분을 정말 싫어합니다).

class TestClass {
    private someMethod_Overload_string(stringParameter: string): void {
        // A lot of code could be here... I don't want to mix it with switch or if statement in general function
        alert("Variant #1: stringParameter = " + stringParameter);
    }

    private someMethod_Overload_number_string(numberParameter: number, stringParameter: string): void {
        alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
    }

    private someMethod_Overload_string_number(stringParameter: string, numberParameter: number): void {
        alert("Variant #3: stringParameter = " + stringParameter + ", numberParameter = " + numberParameter);
    }

    public someMethod(stringParameter: string): void;
    public someMethod(numberParameter: number, stringParameter: string): void;
    public someMethod(stringParameter: string, numberParameter: number): void;

    public someMethod(): void {
        switch (arguments.length) {
        case 1:
            if(typeof arguments[0] == "string") {
                this.someMethod_Overload_string(arguments[0]);
                return;
            }
            return; // Unreachable area for this case, unnecessary return statement
        case 2:
            if ((typeof arguments[0] == "number") &&
                (typeof arguments[1] == "string")) {
                this.someMethod_Overload_number_string(arguments[0], arguments[1]);
            }
            else if ((typeof arguments[0] == "string") &&
                     (typeof arguments[1] == "number")) {
                this.someMethod_Overload_string_number(arguments[0], arguments[1]);
            }
            return; // Unreachable area for this case, unnecessary return statement
        }
    }
}


var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
testClass.someMethod("string for v#3", 54321);
도움이 되었습니까?

해결책

사양에 따르면 Typescript는 지원 방법 과부하를 지원하지만 매우 어색하고 매개 변수의 많은 수동 작업 검사가 많이 포함됩니다.일반 주로 일반 JavaScript에서 오버로드하는 방법에 대한 가장 가까운 것이므로이 검사도 포함되어 있고 Typescript는 불필요한 런타임 성능 비용을 피하기 위해 실제 메소드 본문을 수정하지 않으려 고 시도합니다.

내가 올바르게 이해하면 먼저 각 오버로드에 대한 메소드 선언을 작성한 다음 하나의 인수를 검사하여 어떤 과부하가 호출되었는지 결정할 수있는 메소드 구현을 작성해야합니다.구현의 서명은 모든 과부하와 호환되어야합니다.

class TestClass {
    someMethod(stringParameter: string): void;
    someMethod(numberParameter: number, stringParameter: string): void;

    someMethod(stringOrNumberParameter: any, stringParameter?: string): void {
        if (stringOrNumberParameter && typeof stringOrNumberParameter == "number")
            alert("Variant #2: numberParameter = " + stringOrNumberParameter + ", stringParameter = " + stringParameter);
        else
            alert("Variant #1: stringParameter = " + stringOrNumberParameter);
    }
}
.

다른 팁

명확성을 위해 업데이트됩니다. TypeScript의 메소드 오버로드는 기존 라이브러리에 대한 유형 정의를 표현 해야하는 API를 사용하여 유형 정의를 만들 수 있으므로 유용한 기능입니다.

자신의 코드를 작성할 때는 선택적 또는 기본 매개 변수를 사용하여 오버로드의인지 오버 헤드를 피할 수 있습니다. 이것은 메소드 오버로드에 대한 읽을 수있는 대안이며, 또한 API를 정직하게 정직하게 유지할 수 있습니다.

Typescript 과부하의 일반 법칙은 다음과 같습니다.

할 수 있습니다 과부하 시그라운드와 모든 테스트 통과를 삭제하면 Typescript 오버로드가 필요하지 않습니다

일반적으로 선택 사항 또는 기본 매개 변수 또는 유니온 유형 또는 비트 오브젝트 방향으로 동일한 작업을 수행 할 수 있습니다.

실제 질문

실제 질문은 다음의 과부하를 묻습니다.

someMethod(stringParameter: string): void {

someMethod(numberParameter: number, stringParameter: string): void {
.

이제는 별도의 구현으로 과부하를 지원하는 언어로도 다음과 같이하십시오 (참고 : Typesscript 오버로드는 단일 구현을 공유합니다) - 프로그래머는 일관성을 유지하는 것이 조언입니다. 이것은 서명을 만들 것입니다 :

someMethod(stringParameter: string): void {

someMethod(stringParameter: string, numberParameter: number): void {
.

stringParameter는 항상 필요하므로 먼저가됩니다. 이 파일을 작성하는 Typescript 오버로드로 쓸 수 있습니다.

someMethod(stringParameter: string): void;
someMethod(stringParameter: string, numberParameter: number): void;
someMethod(stringParameter: string, numberParameter?: number): void {
    if (numberParameter != null) {
        // The number parameter is present...
    }
}
.

그러나 TypeScript 과부하의 법칙에 따라 과부하 서명을 삭제할 수 있으며 모든 테스트는 여전히 전달됩니다.

someMethod(stringParameter: string, numberParameter?: number): void {
    if (numberParameter != null) {
        // The number parameter is present...
    }
}
.

실제 질문, 실제 주문

원래 순서로 지속되기로 결심 한 경우 과부하가 다음과 같습니다 :

someMethod(stringParameter: string): void;
someMethod(numberParameter: number, stringParameter: string): void;
someMethod(a: string | number, b?: string | number): void {
  let stringParameter: string;
  let numberParameter: number;

  if (typeof a === 'string') {
    stringParameter = a;
  } else {
    numberParameter = a;

    if (typeof b === 'string') {
      stringParameter = b;
    }
  }
}
.

이제는 매개 변수를 놓을 곳을 일으키는 것은 많은 분기이지만, 당신 이이 순서를 읽는다면이 순서를 보존하기를 원했습니다. / P>

someMethod(a: string | number, b?: string | number): void {
  let stringParameter: string;
  let numberParameter: number;

  if (typeof a === 'string') {
    stringParameter = a;
  } else {
    numberParameter = a;

    if (typeof b === 'string') {
      stringParameter = b;
    }
  }
}
.

이미 이미 분지

물론 우리가해야 할 유형 검사의 양이 주어지면 가장 좋은 대답은 단순히 두 가지 방법을 갖는 것입니다 :

someMethod(stringParameter: string): void {
  this.someOtherMethod(0, stringParameter);
}

someOtherMethod(numberParameter: number, stringParameter: string): void {
  //...
}
.

나는 원한다.이 기능을 너무 많이 원하지만 Typescript는 과부하 된 메소드가없는 Untypped JavaScript로 상호 운용해야합니다.I.E.E. 과부하 메소드가 JavaScript에서 호출되는 경우 하나의 메소드 구현에만 전달 될 수 있습니다.

코드 인쇄에 대한 몇 가지 관련 토론이 있습니다.예를 들어,

https://typescript.codeplex.com/workitem/617

Typescript는 모든 ifing 및 전환을 생성해야합니다. 그래서 우리는 그것을 할 필요가 없으므로

사용하지 않는 이유 선택적 속성 정의 인터페이스 함수 인수로..

이 질문의 경우 일부 선택적 속성으로 정의된 인라인 인터페이스를 사용하면 아래와 같은 코드를 직접 만들 수 있습니다.

class TestClass {

    someMethod(arg: { stringParameter: string, numberParameter?: number }): void {
        let numberParameterMsg = "Variant #1:";
        if (arg.numberParameter) {
            numberParameterMsg = `Variant #2: numberParameter = ${arg.numberParameter},`;
        }
        alert(`${numberParameterMsg} stringParameter = ${arg.stringParameter}`);
    }
}

var testClass = new TestClass();
testClass.someMethod({ stringParameter: "string for v#1" });
testClass.someMethod({ numberParameter: 12345, stringParameter: "string for v#2" });

TypeScript에서 제공되는 오버로드는 다른 의견에서 언급했듯이 다른 정적 언어와 같이 해당 구현 코드를 지원하지 않고 단지 함수의 다양한 서명 목록일 뿐이기 때문입니다.따라서 구현은 여전히 ​​하나의 함수 본문에서만 수행되어야 하므로 Typescript에서 함수 오버로딩을 사용하는 것은 실제 오버로딩 기능을 지원하는 언어만큼 편안하지 않습니다.

그러나 레거시 프로그래밍 언어에서는 사용할 수 없는 TypeScript에는 여전히 새롭고 편리한 기능이 많이 있습니다. 여기서 익명 인터페이스의 선택적 속성 지원은 레거시 함수 오버로딩의 편안한 영역을 충족시키는 접근 방식이라고 생각합니다.

자바 스크립트에는 오버로드 개념이 없습니다.TypeScript는 C # 또는 Java가 아닙니다.

그러나 Typescript에서 오버로드를 구현할 수 있습니다.

이 게시물을 읽으십시오 http://www.gyanparkash.in/function-verloading-in-typescript/ <./ a>

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top