2016-11-13 3 views
2

다형성 에 "텍스트 북"사용 사례가 있다고 생각하며 작동하지 않고 있으며이 문제를 파악할 수 없습니다. 나는이 복제 가능한 일부 abstract 기본 클래스를 상상, 예를 들면 : 나는이 작업을 수행 할 때, 나는 오류가 발생다형성이 TypeScript

class Y extends X { 
    constructor(private x: number) { super() } 
    clone(): this { return new Y(this.x + 1); } 
} 

:

abstract class X { 
    abstract clone(): this; 
} 

지금 나는 clone 구현을 제공하는 기본 클래스를 구현하려면 그 말은 Type Y is not assignable to type 'this'입니다. 나는 완전히 혼란스러워. 여기서 전달하고자하는 것은 유형 제한으로, X의 서브 클래스에 clone 메소드가 호출 된 경우, 돌아 오는 것의 유형이 부속 유형과 동일하게됩니다. 이 정확히 다형성 this은 무엇입니까? 여기서 내가 뭘 잘못하고 있니?

Here is a link이 코드는 TypeScript 놀이터에 있습니다.

답변

1

아니요, 지금 상황에 따라이 유형의 지원되는 사례는 아닙니다. 반환 형식이 this 인 메서드는이 메서드가 파생 클래스에서 재정의되지 않은 경우에도 파생 클래스의 인스턴스를 반환해야합니다.이를 정당화하는 예제는 code in this answer을 참조하십시오. 즉

, 당신에게 그것을 clone Y에서 휴식의 구현을 Z 자체를 clone을 무시하지 않는 경우에도이 코드는 유효해야합니다, abstract clone(): this 선언을 제공하지만.

class Z extends Y { 
    f() { 
     let c: Z = this.clone(); 
    } 
} 

는 그래서 this 반환 형식해야 항상 return this있는 방법처럼 보인다.

업데이트 : github에서이 풀기 요청을 수락하는 것으로 표시된 open issue을 찾았습니다. 나는 그들이 정말로 그것을 지원하려고한다면, 또는 다른 방법으로 컴파일러에 cloneNode을 고칠 계획이 있는지 확신하지 못한다.

+0

감사합니다. 나는 네가 무슨 뜻인지 알 것 같아. 그러나 컴파일러 https://github.com/Microsoft/TypeScript/pull/4910에서이 기능에 대한 PR에서 명시 적으로 언급 되었기 때문에 (실제로 구현되지는 않았지만) "지원되는 사용 사례가 아닙니다"라고 말하는 것은 이상한 일입니다. –

+0

글쎄, 그 홍보는 1 년 전에 합병되었고,이 유스 케이스를 고쳐야 할 문제가 있은 지 6 개월이 지났습니다.이 유스 케이스는 'PR을받는'것으로 표시되었습니다.나는이 유스 케이스가 현재 지원되지 않는다는 말을 덧붙였다. 그들이 정말로 그것을지지하고 싶다면 그것은 오래 전에 고쳐 졌을 것이다. – artem

+0

안전하지 않은 해결 방법이 포함 된 대체 답변을 제공했습니다. –

1

100 % 안전한 방법으로이 작업을 수행 할 수 없다는 것이 맞았 기 때문에 artem의 대답을 올바른 것으로 표시했습니다.

그러나 컴파일러에서 원하는 형식 제약 조건을 적용 할 수있는 방법이 있습니다. 그래서 사람들에게 유용 할 경우를 대비하여이 대답을 포함하기로 결정했습니다. 내 접근법의 단점은 artem이 가리키는 이유, 즉 누군가가 clone 구현을 제공하지 않고 클래스를 확장 할 수 있고 반환 값이 사용자가 주장하는 것이 아닐 수있는 상황을 만들기 때문에 약간 안전하지 않다는 것입니다 그것은.

내 솔루션은 그냥 캐스트를 추가하는 것이 었습니다. 다시 말하지만, 이것은 일반적으로 안전하지 않습니다. 그러나 만약 당신이 수업에서 연장하지 않는다면, 내가 말할 수있는 한 잘 작동합니다. 그래서 내 솔루션이었다 : 당신은 here를 컴파일 완전한 버전을 볼 수 있습니다

class Y extends X { 
    constructor(private x: number) { super() } 
    clone(): this { 
     return new Y(this.x + 1) as this; 
    } 
} 

.

관련 문제