2017-11-30 2 views
1

클래스에 대한 인수 중 하나에 대해 문자열이나 오류를 허용하고 유형을 확인하기 위해 인라인 조건부를 사용할 때 유형 가드가 있도록하고 싶습니다.인라인 조건부 유형 가드

아래의 세 가지 예에서 알 수 있듯이 인라인 조건부 형식에 대한 유형 가드가 지원되지 않는 것 같습니다. 마지막 단 하나만 컴파일됩니다. 이 더있다 : 어떤 이유로 documentation

UPDATE에서 "인라인"라고합니다/다른 블록, 만약 내가 "인라인 조건문"을 말할 때, 나는 형태 (<boolean statement>)? a : b의 의미

, 여러 줄하지 제대로

export class MyError extends Error { 
    public code; name; message 

    constructor(code: number = -1, name: string = '', err?: Error | string) { 
     super() 
     this.name = name 
     this.code = code 
     // no type guards 
     this.message = this.name + (err)? ": " + (err instanceof Error)? err.message : err : '' 
    } 
} 

export class MyError2 extends Error { 
    public code; name; message 

    constructor(code: number = -1, name: string = '', err?: Error | string) { 
     super() 
     this.name = name 
     this.code = code 
     if(err) { 
      // no type guards 
      this.message = this.name + ": " + (err instanceof Error)? err.message : err 
     } else { 
      this.message = this.name 
     } 
    } 
} 

export class MyError3 extends Error { 
    public code; name; message 

    constructor(code: number = -1, name: string = '', err?: Error | string) { 
     super() 
     this.name = name 
     this.code = code 
     // type guards... but at what cost to brevity 
     this.message = this.name 
     if(err) { 
      if(err instanceof Error) { 
       this.message += ": " + err.message 
      } else { 
       this.message += ": " + err 
      } 
     } 
    } 
} 
+1

여부 err.message을 평가합니다 : 예를 들면 다음과 같습니다의 '와'err'은 받아 들일 것입니다 에러 객체 또는 에러 메시지를 출력 할 때,'this.message = \'$ {this.name} '라고 쓰면된다 : $ {err.message || err} \';'. 또한. 당신의 타입이'잘못 되었나요? Error : string'? ** String! == string ** – Rajesh

+0

나는 그것을 좋아한다. 유일한 것은 'err'이 정의되지 않은 경우 ":"가 없어야한다는 것입니다. 그래서 아마 타입을'Error | 문자열 | null', strictNullChecks가 사용 가능하다고 가정하십시오. 업데이트 된 문자열 경우, 건배. –

답변

1

타이프 라이터가 제대로 삼항 문에서 사용되는 타입 가드를 처리합니까 인라인 조건문에 대한 지원 형 가드를 수행 타이프 라이터보다 자바 스크립트,으로한다. 괄호를 사용하면 이러한 문에서 예상 한 것과 다른 동작이 발생합니다.

export class MyError extends Error { 
    public code; name; message 

    constructor(code: number = -1, name: string = '', err?: Error | String) { 
     super() 
     this.name = name 
     this.code = code 
     this.message = this.name + (err ? ": " + (err instanceof Error ? err.message : err) : '') 
    } 
} 

export class MyError2 extends Error { 
    public code; name; message 

    constructor(code: number = -1, name: string = '', err?: Error | String) { 
     super() 
     this.name = name 
     this.code = code 
     if(err) { 
      this.message = this.name + ": " + (err instanceof Error ? err.message : err) 
     } else { 
      this.message = this.name 
     } 
    } 
} 

가 나는 또한 괄호 안의 전체 삼항 문을 둘러싸는 것은 좀 더 읽기 쉽게 할 수 있다고 생각하지만, 그의 개인적인 견해의 문제 : 첫 번째 두 가지 예에서이 같은 코드를 포맷하면 모든 것이 제대로 작동합니다 코스.


왜 삼항 문장에 문제가 있습니까? operator precedence rules 때문에 첫 번째 ? 왼쪽에있는 모든 항목이 같은 표현의 일부이므로 모두가 연결되어 3 자의 전체적인 의미를 변경합니다.

this.message = this.name + ": " + (err instanceof Error)? err.message : err 
// same as: 
(this.name + ": " + (err instanceof Error)) ? err.message : err 
// with values filled in: 
"someName: true" ? err.message : err 

그래서, 위의 코드를 항상 err 당신이 '등의 메시지를 원하는 가정 Error

+0

그래, 그냥 순수 자바 스크립트로 확인하고 문제가 문자열 연결입니다. 우리가 'a = "a :"+ (false) 가면 IE? "a": (거짓)? "b": "c"' "a"'를 얻지 만'a = \'a : $ {(false)? "a": (거짓)? "b": "c"} \'', 우리는 "a : c"를 예상대로 얻습니다. 타이프 스크립트 문제로는 전혀 보이지 않습니다. –

+1

예. [연산자 우선 순위 규칙] ​​(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) 때문에 첫 번째'? '의 왼쪽에있는 모든 것은 같은 부분입니다 표현과 따라서 모두가 서로 연결되어 삼자의 전체 의미를 바꿉니다. – JKillian

+0

이것은 잘 작동합니다 :'this.message = \'$ {this.name} $ {(err)? ":": (오류 발생시)? err.message : err} \'', 첫 번째 예에서 답을 업데이트 해 주시면 받아 들일 수 있습니까? 나중에 읽는 사람들에게는 혼란을주지 않을 것입니다. 즉 그것을 작동시키기 위해 요구되지 않는 브라켓 팅을 보여줍니다. –