2014-12-11 6 views
1

저는 TypeScript와 인터페이스를 가지고 놀았습니다. 나는 다음 코드를 가지고있다.TypeScript 인터페이스 및 구현

interface Control { 
    name: string; 
    onSelect():string; 
} 

class Button { 
    name:string="button"; 
    onSelect = function() { 
     return "hello"; 
    } 
} 

var a:Button = new Button(); 
var b:Control = {"name": "arbitrary", "onSelect":() => { return "ahoy!"; }}; 

var trigger = function(c:Button) { 
    console.log(c.name, "says", c.onSelect()); 
} 

trigger(a); 
trigger(b); 

불평없이 컴파일되어 실행된다. 아무도 내 trigger 함수가 Buttonb이 유형을 가져올 것으로 예상 되더라도 b을 허용하는 이유는 설명 할 수 있습니까? Control입니다.

Button이 명시 적으로 Control을 구현하는 경우에도 Button이 아닌 Control이 필요합니다. 모든 의도 된 목적으로 Button에 추가 구성원이 포함될 수 있습니다.

TypeScript는 구조적으로 동일하기 때문에 구현을 유추합니까? 구현 클래스가 예상되는 인터페이스를 전달할 수 있습니까? (그것은 다른 방법으로 주위 안?)

+1

'Button'에 전용 멤버가있는 경우, 그 멤버 만 (또는 클래스에서 확장 한 클래스) 호환되는 유형으로 간주됩니다. 이것이 원하는 동작 인 경우 '더미'개인 회원 추가를 고려할 수 있습니다. –

+0

알겠습니다. 더미 멤버를 추가 할 생각이었습니다. 당신의 의견으로는, 불필요한 것을 시행하는 엄격한 유형입니까? 그것은 TS의 원리에 어긋나는가? –

+0

나는 거의 생산적이지 않다고 말할 수 있지만 항상 예외가 있습니다. '트리거 '가 실제로 사용하는 멤버가 아닌'버튼'의 양상에 실제로 의존하는 경우 디자인 냄새가 다소 있습니다. –

답변

2

TypeScript documentation on interfaces에 설명 된대로 :

타이프 라이터의 핵심 원칙의

하나는 유형 검사 값이 가지고있는 '모양'에 초점을 맞추고있다. 이것은 때때로 "오리 입력""duck typing"에서

라고 :

이 오리처럼 보이는 그것은 가능성이 오리의 다음에, 오리처럼 수영합니다.

즉, TypeScript는 제공된 개체 또는 형식의 모양 (메서드 및 속성)을 검사합니다. 제공된 객체가 인터페이스에 의해 설명 된 모든 속성 및 메서드를 포함하면 객체는 설명 된 인터페이스와 호환되는 객체로 간주 될 수 있습니다.

예에서 인터페이스와 클래스는 똑같아 보이므로 TypeScript는 개체를 설명 된 인터페이스와 호환되도록 처리합니다.

examine the generated JavaScript의 경우 인터페이스에 대한 언급이 전혀 없습니다. TypeScript 인터페이스는 기본적으로 TypeScript에서 형식 호환성을 확인하는 데 도움이되는 개발자 제공 형식 메타 데이터이기 때문입니다.

+0

엄격한 유형 검사를 수행 할 수있는 방법이 있습니까? 이렇게하면 문제를 일으킬 수있는 미묘한 차이를 쉽게 간과 할 수 있습니다. –

+0

@Andrei - 유형 안전성은 "The JavaScript Way ™"가 아닙니다. 많은 JS 프로그래머는 유형으로 빠르게 날아갈 수 있다는 사실을 좋아합니다. TS는 몇 가지 유형 안전성을 추가하지만 C/C++/C#/Java/등보다 여전히 느슨합니다. –

+0

@Andrie : 또한 John이 언급 하듯이, 객체 나 인터페이스가 다르게 보이게하면 TS가 경고합니다. –

1

모두 당신의 interfaceclass는 당신이 호환되는 객체에 전달되는 Button을 기대하면서 있도록

다른 속성을 추가하는 경우 (문자열을 반환 문자열과 onSelect를 기능을 반환 이름을 가진) 같은 구현이 Button (예 : greeting: string)으로 변경하면 trigger(b)에 오류가 표시됩니다.

interface Control { 
    name: string; 
    onSelect:() => string; // this is another way to write function that returns a string 
} 

class Button implements Control { 
    name:string="button"; 
    onSelect = function() { 
     return "hello"; 
    } 
    greeting: string; // adding this will cause trigger(b) to fail 
} 
+0

엄격한 유형 확인을 사용할 수있는 방법이 있는지 알고 있습니까? 불필요하다고 생각하는 것이겠습니까? –

+0

@AndreiNemes 나는 그것이 필요하다고 생각하지 않는다. 클래스에 다른 종류의 속성이 있거나 인터페이스와 정확히 일치하지 않으면 허용되지 않습니다. – John

+0

입력 해 주셔서 감사합니다! –