유형 스크립트 유형 깊이 발굴. 제2부분: 부족한 값

본고는 최초로 Barbarian Meets Coding에 발표되었다.
TypeScript는 현대적이고 더욱 안전한 자바스크립트 버전으로 웹 개발 분야에서 큰 파문을 일으켰다.이것은 자바스크립트의 초집합으로 자바스크립트 프로젝트를 더욱 효율적이고 확장할 수 있도록 추가 기능, 문법 설탕, 정적 유형 분석을 추가합니다.이것은 일련의 문장의 두 번째 부분이다. 우리는 TypeScript의 전면적인 유형 시스템을 탐색하고 이를 이용하여 매우 건장하고 유지보수 가능한 웹 응용 프로그램을 구축하는 방법을 이해할 것이다.

Haven't read the first part of this series? If you haven't you may want to take a look. There's lots of interesting and useful stuff in there.


JavaScript 및 가치 결여

null은 흔히 10억 달러의 잘못이라고 불린다.Tony Hoare으로 말하자면 그는 1965년에 처음으로 ALGOL에 그것을 도입했다.

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

Tony Hoare and The Billion Dollar Mistake


이런 고통을 간단한 예로 설명해 봅시다. (비록 당신이 그것을 잘 알고 여러 번 겪었을 거라고 확신하지만).
사악한 적을 파괴할 수 있는 기능이 있다고 상상해 보세요.
// Destroy Thy Enemies!!
function attack(target) {
  target.hp -= 10;
}
은마르코프 모형...오늘은 크리스마스입니다.즐거움, 행복과 사랑의 순간.이 예를 더 적합한 예로 바꾸자.
// Love!!!!!
function hug(target) {
  target.happiness += 1000;
}
이제 많이 좋아졌어!우리는 hug의 기능을 이용하여 전 세계에 사랑을 전파하고 싶다고 상상해 보세요.
// Love!!!!!
function hug(target) {
  target.happiness += 1000;
}

const sadJaime = {name: 'jaime', happiness: 0};
hug(sadJaime); // => Wihooo! ❤️
너무 좋아요.모든 것이 계획대로 진행되다.우리는 한 사람을 더욱 즐겁게 한다.Yippi!하지만 우리가 우리의 견본을 좀 더 복잡하게 만들면?
예를 들어 우리는 모든 사람을 안고 싶다.세상 모든 사람처럼.우리는 지금 지구상에 살아있는 모든 사람들을 미리 채워 놓은 신기한 지도를 가지고 있다.따라서 우리는 이것이 확실히 시장에서 유효하다는 것을 검증했다.
// Love!!!!!
function hug(target) {
  target.happiness += 1000;
}

const sadJaime = magicMap.get("Jaime"); // that's me of course
hug(sadJaime); // => Wihooo! ❤️
걸출했어하지만 우리가 찾으려는 사람이 지금 존재하지 않거나 지구에 없다면 어떡하지?
// Love!!!!!
function hug(target) {
  target.happiness += 1000;
}

// returns undefined because Eleanor is in The Good Place
const eleanor = magicMap.get("Eleanor Shellstrop"); 

// brace yourself
hug(eleanor); // => 💥💥💥 Much explosion. 
// Cannot read property happiness of undefined
예.그게 문제야.JavaScript는 Java와 마찬가지로 Ada와 ALGOL도 null의 어려움을 겪었다.비록 자바스크립트의 경우, 상황은 더욱 나빠질 수 있지만, 우리는 단지 두 가지 방법으로 값이 없음을 표시할 수 있기 때문이다. nullundefined이다.

두 키워드 모두 JavaScript에 값이 없음을 나타냅니다.두 가지 모두 상기 예시에서 말한 바와 같이 빈 인용 이상을 초래할 것이다.그렇다면 그들 사이에는 어떤 차이가 있을까?
다음과 같은 몇 가지가 있습니다.null을 반환하는 기본 브라우저 API는 없는 것으로 알고 있습니다.웹 플랫폼에 대한 부족한 값은 항상 undefined입니다.
  • 은 관례에 따라 지역사회는 일반적으로 null을 가치가 없다고 부르고 undefined은 아직 정의되지 않은 것을 나타낸다.개발자는 null을 사용하여 고의로 가치가 부족하다는 것을 나타낼 수 있으며, undefined은 웹 플랫폼으로 정의되지 않은 내용을 알려줄 것입니다.클라이언트와 서버 간에 상호작용을 할 때(예를 들어 Java가 JSON을 JavaScript 전단에 보내는 경우) API도 null을 생성할 수 있습니다.사실 JSON 규범은 null만 지원하지만 undefined은 지원하지 않습니다.
  • undefined 또는 null을 지정하면
  • 의 기본 매개 변수는 동작이 다릅니다.함수에 undefined을 매개 변수로 전달하면 함수는 사용자가 제공한 기본값을 사용합니다.반대로 null을 전달하면 함수는 기본값이 아니라 즐겁게 사용할 수 있습니다.(매우 위험)
  • 상기 모든 내용에 대해 저는 가능한 한 null을 피하고 플랫폼에서 undefined을 생성할 때 처리합니다.그럼에도 불구하고 때로는 선택의 여지가 없이 nullundefined 근처에서만 일할 수 있다.그것들은 불가피하게 빈 인용 이상을 초래할 것이다. 매우 고전적인 미정의 함수는 하나의 함수가 아니다...
    그렇다면 TypeScript는 이 혼란을 해결하는 데 어떻게 도움을 줍니까?

    일. TypeScript 및 누락 값


    따라서 TypeScript에는 부족한 값을 나타내는 두 가지 방법이 없습니다.그것은 네 개가 있다.

    이 네 가지 가치 결핍을 나타내는 방식은 다음과 같다.
  • undefinednull은 JavaScript에서와 같습니다. 왜냐하면 TypeScript는 JavaScript
  • 의 초집합이기 때문입니다.
  • void, 어떤 내용도 반환하지 않는 함수의 반환 유형
  • never, 되돌아오지 않는 함수를 나타내는 되돌아오는 유형
  • 와!두 개가 아니라 네 개??이것은 좋은 물건입니까?답은 긍정적이다.값이 없음을 나타내는 여러 가지 방법이 있기 때문이 아니라 TypeScript에서 nullundefined도 유형이기 때문이다.
    그럼 어때요?
    지난 예시를 봅시다.우리는 Target 인터페이스를 정의하여 happiness의 속성을 가진 모든 것을 표시합니다(이것은 인간, 애완동물 또는 괴물이 안아야 할 전부입니다).
    interface Target {
      happiness: number;
    }
    
    이제 hug 함수에서 사용할 수 있습니다.
    // Love!!!!!
    function hug(target: Target) {
      target.happiness += 1000;
    }
    
    만약 우리가 이전처럼 슬픈 제이미를 안는다면 모든 것이 좋아질 것이다.
    // Love!!!!!
    function hug(target: Target) {
      target.happiness += 1000;
    }
    
    const sadJaime = magicMap.get("Jaime"); // that's me of course
    hug(sadJaime); // => Wihooo! ❤️
    
    그런데 우리가 엘리노를 안으려고 한다면?
    // Love!!!!!
    function hug(target: Target) {
      target.happiness += 1000;
    }
    
    // returns undefined because Eleanor is in The Good Place
    const eleanor = magicMap.get("Eleanor Shellstrop"); 
    
    hug(eleanor); // => 💥 Argument of type 'undefined' is not assignable to parameter of type 'Target'.
    
    우리 잘못했어!!우리가 번역을 받았을 때 틀렸다.즉, 우리가 위에 코드를 입력하면 TypeScript 컴파일러는 우리가 무엇을 잘못했는지 알려준다.함수 hugTarget이 필요하기 때문에 undefined을 드리겠습니다. 이것은 완전히 다른 유형입니다. Target의 어떤 특징도 없습니다. TypeScript 컴파일러가 도움을 줄 것입니다.
    이것이 바로 TypeScript가 nullundefined 유형을 어떻게 이용하여 빈 인용 이상과 무서운 백만 달러 오류를 방지하는가이다.너무 좋아요, 그렇죠?

    엄격한 제로 검사

    The behavior we've just seen, where TypeScript will prevent you from shooting yourself in the foot with null or undefined is called strict null checking. It is a feature of the TypeScript compiler which was added in TypeScript 2.0 an which needs to be enabled in your tsconfig file via the stricNullChecks setting. In general, it is strongly advised to aspire to having your TypeScript configuration be as strict as possible. That way you'll take the most advantage of TypeScript's type system and you'll be able to write safer and more maintainable applications.


    그냥 재미로.우리는 어떻게 상기 함수를 다시 써서 null 또는 undefined을 허용하고 자바스크립트 버전과 같은 효과를 냅니까?한 가지 방법은 다음과 같습니다.
    // Love!!!!!
    function hug(target: Target | undefined | null) {
      target.happiness += 1000;
    }
    
    따라서 이 함수의 매개 변수는 Target, undefined 또는 null이 될 수 있음을 TypeScript에 명확하게 알려 드립니다.또는:
    // Love!!!!!
    function hug(target?: Target | null) {
      target.happiness += 1000;
    }
    
    그 중에서 우리는 선택할 수 있는 매개 변수를 사용하여 target? 기호를 사용하는데 이것은 Target | undefined의 약어이다.

    Null 사용 또는 정의되지 않음


    경우에 따라 null 또는 undefined을 사용해야 합니다.JavaScript로 구현된 타사 라이브러리를 사용한다고 가정하면 null 또는 undefined으로 돌아가는 데 관심이 없습니다.당신은 강력한 전사가 있을 것입니다. 곧 칼로 감자를 베어 크리스마스 저녁으로 삼을 것입니다. 그래서 다음과 같은 내용을 쓰십시오.
    const warrior = tavern.hireWarrior({goldCoins: 2});
    
    if (warrior !== null 
        && warrior !== undefined
        && warrior.sword !== null 
        && warrior.sword !== undefined){
      warrior.sword.slash();
    }
    
    당신이 사용하는 전사 고용 API는 자바스크립트로 작성되었습니다. 전사가 돌아왔는지, 전사가 검이 있는지 확인할 수 없습니다. 안전을 위해서 일련의 비어 있는/정의되지 않은 검사를 작성해야 합니다.
    TypeScript(>=3.7)에는 대체적이고 지루하지 않은 버전이 있습니다.링크 연산자 ?.(옵션)을 사용하면 위의 예제를 다시 쓸 수 있습니다.
    warrior?.sword?.slash();
    // The ? is often called the Elvis operator
    // because this ?:-p
    
    즉, slash과 그녀의 warrior이 정의되지 않은 것도 아니고null도 아닐 때만 우리는 sword 방법을 사용한다.만약 네가 나에게 묻는다면, 그것은 더욱 좋은 선택이다.
    평판이 엉망인 작은 술집에서 전사를 고용해서 이 문제를 해결하는 또 다른 선택은 일이 잘못되었을 때 우리가 그것을 사용할 수 있는 기본값이 있다는 것이다.따라서 위의 공격을 확보하기 위해 우리는 항상 강력한 전사가 확실히 존재하는 것을 확보하는 방법을 따를 수 있다.
    let warrior = tavern.hireWarrior({goldCoins: 2});
    if (!warrior) {
      warrior = new Warrior('Backup Plan Joe');
    }
    if (!warrior.sword) warrior.equip(new RustySword());
    
    warrior.sword.slash();
    
    TypeScript는 null에 대한 대체 검사와 다른 값 모드가 할당되었는지 확인하는 방법도 있습니다. null 병합 연산자 ??입니다.??을 사용하면 위 예제를 단순화할 수 있습니다.
    let warrior = tavern.hireWarrior({goldCoins: 2}) 
                  ?? new Warrior('Backup plan Joe');
    
    if (!warrior.sword) warrior.equip(new RustySword());
    
    warrior.sword.slash();
    
    괜찮죠??.?? 연산자는 TypeScript에서 값이 부족한 문제를 해결하는 데 더욱 쉽습니다.

    Optional chaining and the nullish coalescing operator were approved as part of ES2020 and are now official features of the JavaScript language. Yey!


    가치 부족을 모의하는 더 좋은 방법이 있습니까?


    매우 멋진 모델링 값이 없는 방법은 Maybe 단자 형식의 함수 프로그래밍에서 나온다.이 시리즈의 후속 글에서 우리가 범용 유형의 비밀을 섭렵한 후에 우리는 이 주제를 다시 토론하고 TypeScript가 이러한 함수식 프로그래밍 모델을 어떻게 지원하는지 이해할 것이다.

    어쨌든

    nullundefined은 JavaScript 프로그램에서 심각한 손상을 초래할 수 있습니다.그것들은 운행할 때 임의로 중단할 수도 있고, 대량의 예방 원인과 방어 코드를 작성하도록 강요할 수도 있다. 이 코드들은 매우 지루하고 핵심 업무 논리를 모호하게 할 수도 있다.
    TypeScript에서는 nullundefined도 유형입니다.이것은 엄격한 빈 검사와 결합하여 컴파일할 때 프로그램이 빈 인용 이상의 영향을 받지 않도록 보호합니다.따라서 실행할 때 버그를 일으킬 수 있는 오류를 범하면 즉시 피드백을 받고 복구할 수 있습니다.null 또는 undefined을 사용해야 할 경우 TypeScript 3.7과 ES2020은 두 가지 기능을 통해 고통을 줄일 수 있습니다.null과 정의되지 않은 것을 처리할 때, 선택할 수 있는 링크와nullcoalescing 조작부호는 대량의 입력을 절약할 수 있습니다.
    오늘은 여기까지.네가 이 문장을 좋아해서 새로운 것을 배웠으면 좋겠다.다음까지 안녕히 계세요. 그리고 좋은 날이 있을 거예요.
    JavaScript에서 빈 참조 예외는 더 일반적인 TypeError로 간주됩니다.다른 언어 (예: C# 또는 Java) 에서처럼 비어 있는 참조 예외에만 적용되는 특정 오류는 없습니다 (Null ReferenceException). 

    좋은 웹페이지 즐겨찾기