&& 연산자가 두 번째 피연산자의 유형을 생성하는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com//questions/12693787

  •  12-12-2019
  •  | 
  •  

문제

TypeScript 사양은 §4.15.6에 다음과 같이 명시되어 있습니다. && 운영자:

&& 연산자는 피연산자가 모든 유형이 되도록 허용하고 다음을 생성합니다. 두 번째 피연산자와 동일한 유형의 결과.

자바스크립트에서는 && 연산자는 거짓이면 첫 번째 피연산자를 반환하고, 그렇지 않으면 두 번째 피연산자를 반환합니다(ECMA-262 §11.11 참조).

즉, 왼쪽 피연산자가 거짓이면 && 왼쪽 피연산자의 유형과 일치하는 값을 반환합니다.예를 들어,

typeof ( false && {}      ) === "boolean" // true
typeof ( ''    && 1       ) === "string"  // true
typeof ( null  && "hello" ) === "object"  // true
typeof ( NaN   && true    ) === "number"  // true

위에 인용된 규칙에 따르면 Typescript는 다음과 같습니다. 틀리게 위 표현식의 유형을 예측해 보세요. Object, Number, String 그리고 Boolean, 각각.

뭔가 빠졌나요?유형을 만드는 데에는 타당한 이유가 있습니까? && 표현식이 두 번째 피연산자의 유형과 일치합니까?결과 유형이 다음과 같이 동작하면 안 되나요? || 연산자를 사용하고 두 피연산자 중 가장 일반적인 유형을 반환합니다. Any 가장 좋은 공통 유형이 없다면?

도움이 되었습니까?

해결책

간단히 말해서 모든 사람을 만족시킬 수 있는 해결책은 없습니다.

다음과 같은 일반적인 관용어를 고려해보세요.

var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
    printAddressLabel(address); // Signature: (Address) => void
} else {
    // Couldn't find the customer or the customer has no address on file
}

Customer와 Address 사이에 가장 공통적인 유형이 없기 때문에 포기하고 'address'가 'any'라고 결정하는 것은 매우 어리석은 일입니다.

&& 연산자가 사용되는 대부분의 경우 유형은 다음 중 하나입니다. 이미 match 또는 &&는 위와 같이 값 통합 방식으로 사용됩니다.두 경우 모두 오른쪽 피연산자의 유형을 반환하면 사용자에게 예상되는 유형이 제공됩니다.

이 시점에서 형식 안전성이 기술적으로 무너지고 있지만 오류가 발생할 가능성이 있는 방식은 아닙니다.결과 값의 진실성을 테스트하거나(이 경우 유형은 다소 관련이 없음) 일부 작업에 대해 추정 오른쪽 피연산자를 사용할 것입니다(둘 다 수행하는 위의 예).

나열된 예제를 보고 왼쪽 피연산자가 확실히 참인지 거짓인지 가정하고 반환 값에 대해 작동하는 정상적인 코드를 작성하려고 하면 훨씬 더 명확해집니다. 할 수 있는 일이 많지 않습니다. 하다 '모든' 인수 위치 또는 진실성 테스트에 아직 들어가지 않은 'false && {}'를 사용합니다.


부록

위의 내용을 납득하지 못하는 사람들도 있으므로, 여기에는 다른 설명이 있습니다.

TypeScript 유형 시스템에 세 가지 새로운 유형이 추가되었다고 잠시 가정해 보겠습니다. Truthy<T>, Falsy<T>, 그리고 Maybe<T>, 유형의 가능한 진실/거짓 값을 나타냅니다. T.이러한 유형에 대한 규칙은 다음과 같습니다.

  1. Truthy<T> 정확히 다음과 같이 행동합니다 T
  2. 다음 속성에 액세스할 수 없습니다. Falsy<T>
  3. 유형의 표현 Maybe<T>, 에서 조건으로 사용되는 경우 if 블록은 Truthy<T> 그 사람 몸에 if 블록과 Falsy<T> 에서 else 차단하다

이렇게 하면 다음과 같은 작업을 수행할 수 있습니다.

function fn(x: Maybe<Customer>) {
   if(x) {
      console.log(x.address); // OK
   } else {
      console.log(x.phone); // Error: x is definitely falsy
   }
   console.log(x.name); // Warning: x might be falsy!
}

지금까지는 꽤 좋았습니다.이제 && 연산자에 대한 유형 규칙이 무엇인지 알아낼 수 있습니다.

  • Truthy<T> && x 오류여야 합니다. 왼쪽이 진실인 것으로 알려지면 방금 작성했어야 합니다. x
  • Falsy<T> && x 오류여야 합니다. 왼쪽이 거짓인 것으로 알려진 경우 x 접근할 수 없는 코드입니다
  • Maybe<T> && x 생산해야 한다...무엇?

우리는 그 결과를 알고 있다 Maybe<T> && x 유형의 잘못된 값이 됩니다. T, 또는 x.생산할 수 없습니다 Truthy<T> (하지 않는 한 T == 유형 x 어떤 경우에는 이 전체 논의가 문제가 됩니다.)이것을 새로운 유형이라고 부르자 Falsy<T> XOR Maybe<U>.

규칙은 무엇이어야 하는가? Falsy<T> XOR Maybe<U> BE?

  • 분명히 다음의 속성을 사용할 수 없습니다. T 그 위에.값이 유형인 경우 T, 그것은 거짓이며 사용하기에 안전하지 않습니다.
  • 으로 활용할 수 있어야 합니다. Maybe<U>, 부터 Falsy<T> 그리고 Falsy<U> 같은 행동을 가지고
  • 다음의 속성을 사용할 수 없어야 합니다. U, 값이 여전히 거짓일 수 있기 때문입니다.
  • 당신이 그것을 사용하는 경우 if 테스트를 거쳐야 합니다. Truthy<U> 그 블록에 if 성명

다시 말해서, Falsy<T> XOR Maybe<U> ~이다 Maybe<U>.그것은 모두 동일한 규칙을 따릅니다.여기에 이런 이상한 문자를 추가하여 유형 시스템을 전혀 복잡하게 만들 필요가 없습니다. XOR 필요한 모든 사양에 맞는 유형이 이미 존재하기 때문입니다.

이는 누군가에게 상자를 주고 "이것은 빈 쓰레기 상자이거나 재활용품이 가득한 상자입니다"라고 말하는 것과 약간 비슷합니다.상자의 내용물을 재활용 쓰레기통에 안전하게 비울 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top