2017-01-12 1 views
3

내가 만난 가장 일반적인 ES6 관련 실수 중 하나는 맞춤법 오류 constructor입니다. 클래스는 기본 생성자 메서드를 가지고 있기 때문에 분명히생성자 메서드 맞춤법 오류 방지

, 이것은 어떤 영향을하지 않습니다

interface IConstructor { 
    constructor: Function; 
} 

class Foo implements IConstructor { 
    contructor() { ... } 
} 

방법이 문제 바람직 컴파일시에, 타이프 라이터로 해결 될 수 있는가?

+0

* "내가 만난 가장 일반적인 ES6 관련 실수 중 하나는 철자가 틀린 생성자 방법입니다."* - ReactJS와 같은 느낌입니다. 'componentDldMount' (misspell? 참조)를 작성하는 것만으로도 자동적으로 실패 할 것이고, 당신 스스로 끔찍한 버그를 추적 할 수 있습니다. 이것이 바로 정확한 메소드 이름 일치로 후크를 제공하는 API를 일반적으로 무시하는 이유입니다. 여기서 할 수있는 일은 IDE에 'ctor'를 작성하여 생성자 메소드를 생성하는 스 니펫 (snippet)을 생성하는 것입니다. –

+0

@JohnWeisz 예, 스 니펫이 작동 할 수 있습니다. 그러나 Plunker에서 프로토 타입을 작성하는 것은 여전히 ​​고통 스러울 수 있습니다. Angular 2에서 hook 메소드는 인터페이스를 통해 강제 실행되며,'class Foo는 OnInit'을 구현합니다. Flow와 비슷한 일을 할 수 있습니다. – estus

+0

Angular 2의 문제는 선택적인 후크 방법의 철자를 강제로 지정할 수있는 방법이 없다는 것입니다 (여러 인터페이스를 통해 메소드를 배포하는 것 외에는 오류가 발생하기 쉽습니다). 당신은'constructor'이 선택적인 네이티브 훅 메소드라고 말할 수 있습니다. 불행히도 데코레이터를 생성자와 함께 사용할 수는 없지만 데코레이터 기반 접근 방식은 IMO가 훨씬 우수합니다. '@ componentDidMount'는 TypeScript 컴파일러에 의해 감지되기 ​​때문에 잘못 입력 할 수 있습니다. –

답변

1

쉽게 보호 할 수는 없지만 보호 할 수는 없습니다.

class Base { 
    protected constructor() {} 
} 

class A extends Base { 
    contructor() { } 
} 

let a = new A(); // error: Constructor of class 'Base' is protected and only accessible within the class declaration 

(code in playground)

을하지만 그 이상되는 거리가 멀다입니다 :

당신은 예를 들어, 해결할 수 있습니다.

+0

감사합니다. 이상적 (여분의'super()'가 필요하다).하지만 이미 아주 좋다. – estus

+1

'super()'를 호출 할 필요가있을뿐만 아니라 기본 클래스를 서브 클래스 화해야합니다. 이미 그렇게하고 있다면 문제가되지 않습니다. 그렇지 않으면 중복되는 느낌이 들게됩니다. 하지만 컴파일 오류가 발생하는 또 다른 방법은 생각할 수 없습니다. –

0

기본적으로 메소드 선언입니다. 파생 된 맞춤법 오류를 방지 할 수 없습니다.

+0

가능합니다. 인터페이스를 통해. 하지만'constructor' (내 downvote, btw) 아닙니다. – estus

+2

인터페이스를 통해 인터페이스 메소드를 구현해야합니다. 이 경우 철자가 틀린 메서드 이름을 구현하는 데 방해가되지 않습니다. –

+1

문제는'contructor' 철자가 틀린 것이 아니라 스스로 해를 끼치 지 않는다는 것입니다. 문제는'Foo' 클래스가 명시 적으로 정의하지 않은'constructor' 메소드를 명시 적으로 정의하지 않았기 때문입니다. 다른 메소드의 경우 추상 메소드를 사용하여 추상 클래스를 확장하여 방지 할 수 있지만 생성자 메소드에서는 작동하지 않습니다. – estus

1

인터페이스는 유형과 유형 소비자 간의 계약입니다. 클래스를 코드를 사용하여 인수없이 인스턴스화 할 수 있는지 확인하려는 경우 이미 완료된 것입니다. 제로 파라미터 생성자를 선언했는지 여부에 관계없이 유형의 소비자는 인수없이 인스턴스를 생성 할 수 있습니다.

한편 유형 시스템을 사용하여 무언가 인이없는 0 매개 변수 생성자가 정의되었는지 확인하려면 정적 유형 검사가 적합합니다. 아마 당신의 단위 테스트에서 이것을 검증 해보십시오.

class Foo implements IConstructor { 
    constructor() {} 
} 

유일한 차이점 중요한 것은 :

class Foo implements IConstructor { 
    constructor() { 
     // ... 
     /* Is this */ 
     // ... 
    } 
} 

그리고 그 동작을 확인하는

class Foo implements IConstructor { 
} 

이에서 의미있는 차이가 없다 :이 즉

, 부분 검사는 유형 검사보다 단위 검사에 더 적합합니다.

+1

예, 이것은 단위 테스트로 해결할 수있는 문제입니다. 그러나 Typescript의 이점 대부분은 테스트 커버리지로 대체 될 수 있습니다. Typescript가 훌륭한 이유 중 하나는 디자인 타임에 문제를 감지 할 수 있다는 것입니다. – estus

+0

@estus TypeScript의 장점 대부분이 단위 테스트로 대체 될 수 있다고해서 역행을위한 좋은 사례는 아닙니다. 단위 테스트에서 사용할 수있는 대부분의 도구는 유형 검사기에 포함될 수 없으며 너무 길어서는 안됩니다. –

+0

사실입니다. 이 사건이 유형 검사기에 속한다고 생각하십시오. 함축 된 생성자가 합리적인 방법으로 TS에서이를 처리 할 수 ​​없도록하는 것은 슬픈 일입니다. 또 다른 문제점은 생성자 메소드 ('Foo.prototype.constructor')는 유닛 테스트에서 간과 할 수 없기 때문에 테스트는 간접적이어야하며, dev는 테스트가 실패한 이유를 알아 내는데 약간의 시간을 낭비합니다. 게다가 맞춤법 오류가있는 생성자에 개인적으로 문제가있는 대부분의 시간에는 테스트 커버리지가없고 빠른 시간 안에 낭비되는 빠른 프로토 타입이있었습니다. – estus

2

이것을 방지하고 입력시 저장하는 가장 좋은 방법은 텍스트 편집기에서 미리보기를 사용하여 생성자를 만드는 것입니다.

예를 들어 제 편집자에서 ctor을 입력하고 탭을 누르면 기본 생성자가 생성됩니다. 당신은 당신이 사용하는 편집기에 상관없이 이것을 수행하는 방법을 찾아야 할 것입니다. 대부분의 편집자는 스 니펫을 지원합니다 (그렇지 않은 경우 편집자를 전환해야합니다).

이 문제를 방지하기위한 추가 코드 작성은 과도한 작업입니다.

0

생성자 메서드 맞춤법 오류와 관련된 문제를 해결하기 위해 일반적으로 알지 못하는 모든 오 프린트를 포함하는 인터페이스를 작성했습니다.

interface IConstructor { 
    constructor: Function; 
    constuctor?: void; 
    construtor?: void; 
    contructor?: void; 
    cnstructor?: void; 
    // ... 
} 

// Type '() => void' is not assignable to type 'void'. 
class Foo implements IConstructor { 
    contructor() { } 
} 

생성자 메서드를 지정해야하지만 누락 된 문제는 해결되지 않습니다.

더 과감한 접근 방법은 서브 클래스를 사용하는 것입니다 (the other answer에서 제안).