안전하고 “증명 가능하게 올바른” 타입 시스템 적용하기. 그 대신 정확성과 생산성 사이의 균형을 노린다. Apply a sound or "provably correct" type system. Instead, strike a balance between correctness and productivity.
arg: { x: string | null }
은 인자로 받는 arg
에 x
라는 필드가 존재하고, 해당 필드가 string
또는 null
타입이라는 의미이다. 함수 내부를 보면, 먼저 arg.x
가 null
인지 여부를 체크한다. 만약 null
이 아니라면 arg.x
는 문자열이라 판단하고, 안심하고String.prototype.substr
을 호출한다.window.alert
함수를 덮어쓴다. 새로 정의된 window.alert
는 호출되는 순간 a.x
를 null
로 바꾸어버린다. null
에는 substr
메소드가 없으므로 getFirstThreeCharsUnsafe
내의 arg.x.substr(0, 3)
가 불리는 순간 TypeError: Cannot read property 'substr' of null
오류가 던져진다. 타입 검사를 통과했음에도 런타입 오류가 발생하는 것이다.if
블록 안에서도 함수가 하나라도 호출 된 시점에서, 해당 블록에 들어오게 한 조건문이 참일 것이라는 가정을 버려야 한다. 위 함수를 아래와 같이 다시 고치면 문제는 해결된다.getFirstThreeCharsSafe
처럼 함수 호출이 일어날 때마다 조건 검사를 다시 하도록 강제해야 한다. 실제로 안전성을 최우선 과제로 천명한 Flow는 getFirstThreeCharsUnsafe
를 통과시켜 주지 않는다.if
문들을 살펴보고 이런 ‘안전한’ 타입 시스템이 통과 시켜 줄 코드가 얼마나 되는지 찾아보라!getFirstThreeCharsUnsafe
와 같은 사용법을 허용한다..flow
확장자를 가지며 내용이 비어 있지 않은 파일이 약 2천 개 정도 존재했다. 타입스크립트의 경우 GitHub 검색의 한계와 더불어 node_modules
파일을 전부 커밋한 저장소가 너무 많아 신뢰할만한 수를 얻기 어려웠지만, 다른 지표들로 미루어보아 내부 타입 정의의 수 역시 Flow보다 많을 것으로 추정한다.