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 언어로 메서드 오버로드를 수행하는 방법
사양에 따르면 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 오버로드의 일반적인 법칙은 다음과 같습니다.
일반적으로 옵션 파라미터 또는 기본 파라미터, 결합타입 또는 객체방향으로 동일한 작업을 수행할 수 있습니다.
실제 질문
실제 질문은 다음과 같은 과부하를 요구합니다.
someMethod(stringParameter: string): void {
someMethod(numberParameter: number, stringParameter: string): void {
현재는 개별 구현으로 과부하를 지원하는 언어에서도 사용할 수 있습니다(주의:TypeScript 오버로드가 1개의 구현을 공유합니다). 프로그래머는 순서를 일관되게 하기 위한 조언입니다.그러면 시그니처가 다음과 같이 됩니다.
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;
}
}
}
파라미터를 어디에 배치할지를 결정하기 위해서는 많은 분기가 필요합니다만, 지금까지 읽고 있는 경우는, 이 순서를 확실히 유지하고 싶다고 생각하고 있었습니다.그런데 잠깐, TypeScript 오버로드의 법칙을 적용하면 어떻게 될까요?
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는 오버로드되지 않은 자바스크립트와 상호 운용할 수 있어야 합니다.오버로드된 메서드가 JavaScript에서 호출되면 하나의 메서드 구현에만 디스패치할 수 있습니다.
코드플렉스에 관한 몇 가지 관련 논의가 있습니다.
https://typescript.codeplex.com/workitem/617
저는 여전히 TypeScript가 모든 if's와 switching을 생성해야 한다고 생각합니다.그래서 우리는 그것을 할 필요가 없습니다.
옵션의 속성 정의 인터페이스를 function 인수로 사용하지 않는 이유는 무엇입니까?
이 질문의 경우 일부 옵션속성에 의해 정의된 인라인인터페이스를 사용하면 다음과 같은 코드를 직접 만들 수 있습니다.
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에서의 함수 오버로드 사용은 실제 오버로드 기능을 지원하는 언어만큼 편안하지 않습니다.
다만, 기존의 프로그래밍 언어에서는 이용할 수 없는 새롭고 편리한 것이 많이 있습니다.익명의 인터페이스에서의 옵션 속성 지원은 레거시 기능의 과부하로부터 편안한 영역을 충족시키기 위한 접근법이라고 생각합니다.
메서드 오버로드의 종류가 많은 경우 다른 방법은 모든 arg를 내부에 포함하는 클래스를 만드는 것입니다.따라서 임의의 순서로 원하는 파라미터만 전달할 수 있습니다.
class SomeMethodConfig {
stringParameter: string;
numberParameter: number;
/**
*
*/
constructor(stringParameter: string = '012', numberParameter?: number) { // different ways to make a param optional
this.numberParameter = 456; // you can put a default value here
this.stringParameter = stringParameter; // to pass a value throw the constructor if necessary
}
}
또한 기본값으로 생성자를 만들거나 일부 필수 인수를 전달할 수도 있습니다.그럼 이렇게 사용하세요.
const config = new SomeMethodConfig('text');
config.numberParameter = 123; // initialize an optional parameter only if you want to do it
this.SomeMethod(config);
언급URL : https://stackoverflow.com/questions/12688275/how-to-do-method-overloading-in-typescript
'programing' 카테고리의 다른 글
WordPress 사이트에서 Python 앱을 실행할 수 있습니까? (0) | 2023.03.20 |
---|---|
발견되지 않은 오류: WP_Term 형식의 개체를 배열로 사용할 수 없습니다. (0) | 2023.03.20 |
우체부: 중첩된 JSON 개체 전송 (0) | 2023.03.20 |
Spring Boot 및 IntelliJ Idea를 사용하여 데이터베이스에서 엔티티 클래스를 생성하려면 어떻게 해야 합니까? (0) | 2023.03.20 |
각진 이유JS 통화 필터는 괄호로 음수를 포맷합니까? (0) | 2023.03.20 |