TypeScript 고급 유형 — 활자 호위

아마존에서 내 책 보기https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
지금 http://jauyeung.net/subscribe/에 내 이메일 목록을 구독하십시오.
TypeScript는 동적 유형 코드를 쉽게 작성할 수 있는 다양한 고급 유형 기능을 제공합니다.또한 TypeScript의 유형 검사 기능을 사용하면서 JavaScript의 동적 기능을 유지할 수 있도록 하기 때문에 기존 JavaScript 코드의 도입을 촉진시켰다.
TypeScript에는 교차 유형, 결합 유형, 유형 보호, 공백 유형 및 유형 별칭 등 다양한 고급 유형이 있습니다.본문에서 우리는 유형 보호를 소개할 것이다.

활자 호위
대상이 어떤 유형에 속하는지 확인하기 위해서, 우리는 우리가 원하는 구성원과 값의 데이터 유형을 검사하기 위해 자신의 유형 보호기를 만들 수 있다.이를 위해 TypeScript와 JavaScript 연산자를 사용할 수 있습니다.
유형을 검사하는 방법의 하나는 as 연산 기호를 사용하여 유형을 가진 대상을 강제로 변환하는 것이다.이것은 연합 유형을 구성하는 모든 유형에 지정되지 않은 속성에 접근하는 데 필요합니다.
예를 들어, 다음 코드가 있는 경우

interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
console.log(person.name);
그러면 TypeScript 컴파일러는 name 대상의 person 속성에 접근할 수 없습니다. Person 형식에서만 사용할 수 있고 Employee 형식에서는 사용할 수 없기 때문입니다.따라서 다음과 같은 오류가 발생합니다.
Property 'name' does not exist on type 'Person | Employee'.Property 'name' does not exist on type 'Employee'.(2339)
이 경우, 우리는 TypeScript에서 사용할 수 있는 유형 단언 연산자를 사용하여 유형을 Person 대상으로 강제로 변환해서 name 속성에 접근해야 한다. 우리는 이 속성이 person 대상에 존재한다는 것을 안다.
이를 위해 다음과 같이 as 연산자를 사용합니다.
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
console.log((person as Person).name);
as 연산자를 사용하여 우리는 TypeScript 컴파일러personPerson 클래스에 속한다고 현저하게 알려주면 name 인터페이스의 Person 속성에 접근할 수 있다.

유형 술어
대상의 구조를 검사하기 위해서 우리는 유형 술어를 사용할 수 있다.형식 술어는 코드입니다. 주어진 속성 이름과 관련된 값이 있는지 확인합니다.
예를 들어, 객체에 isPerson 유형의 속성이 있는지 확인하기 위해 새 함수Person를 작성할 수 있습니다.
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const isPerson = (person: Person | Employee): person is Person => {
  return (person as Person).name !== undefined;  
}
if (isPerson(person)) {
  console.log(person.name);  
}
else {
  console.log(person.employeeCode);  
}
위의 코드에서 isPerson 형식person is Person을 되돌려줍니다. 이것은 우리의 유형 술어입니다.
위 코드에서처럼 함수를 사용하는 경우 결합 유형이 두 가지 유형으로 구성되면 TypeScript 컴파일러가 자동으로 유형 범위를 좁힙니다.if (isPerson(person)){ ... } 블록에서 우리는 Person 인터페이스의 모든 구성원을 방문할 수 있다.
그러나 두 가지 이상의 유형이 연합 유형을 구성한다면 소용없다.예를 들어, 다음 코드가 있는 경우
interface Animal {
  kind: string;
}
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee | Animal = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const isPerson = (person: Person | Employee | Animal): person is Person => {
  return (person as Person).name !== undefined;  
}
if (isPerson(person)) {
  console.log(person.name);  
}
else {
  console.log(person.employeeCode);  
}
그런 다음 TypeScript 컴파일러가 코드 컴파일을 거부하고 다음 오류 메시지를 받습니다.
Property 'employeeCode' does not exist on type 'Animal | Employee'.Property 'employeeCode' does not exist on type 'Animal'.(2339)
이것은 else 자구의 유형을 모르기 때문이다. 왜냐하면 Animal 또는 Employee 이기 때문이다.이 문제를 해결하기 위해서 우리는 다음 코드에서 한 것처럼 다른 if 블록을 추가해서 Employee 유형을 검사할 수 있다.
interface Animal {
  kind: string;
}
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee | Animal = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const isPerson = (person: Person | Employee | Animal): person is Person => {
  return (person as Person).name !== undefined;  
}
const isEmployee = (person: Person | Employee | Animal): person is Employee => {
  return (person as Employee).employeeCode !== undefined;  
}
if (isPerson(person)) {
  console.log(person.name);  
}
else if (isEmployee(person)) {
  console.log(person.employeeCode);  
}
else {
  console.log(person.kind);  
}

전화 교환원
구조를 검사하여 데이터 유형을 확정하는 또 다른 방법은 in 연산자를 사용하는 것이다.JavaScriptin 연산자처럼 객체에 속성이 있는지 확인하는 데 사용할 수 있습니다.
예를 들어, 객체가 Person 객체인지 확인하려면 다음 코드를 작성할 수 있습니다.
interface Animal {
  kind: string;
}
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee | Animal = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const getIdentifier = (person: Person | Employee | Animal) => {
  if ('name' in person) {
    return person.name;
  }
  else if ('employeeCode' in person) {
    return person.employeeCode
  }
  return person.kind;

}
getIdentifier 함수에서 우리는 일반 자바스크립트 코드에서처럼 in 연산자를 사용한다.만약 우리가 하나의 유형에 특유한 구성원의 이름을 검사한다면, TypeScript 컴파일러는 person 블록의 if 대상의 유형을 앞에서 말한 바와 같이 추정할 것이다.namePerson 인터페이스에만 있는 속성이기 때문에 TypeScript 컴파일러는 그 중의 모든 내용이 Person 대상이라는 것을 알 수 있을 정도로 똑똑하다.
마찬가지로 employeeCodeEmployee 인터페이스의 한 구성원일 뿐이기 때문에 그 안의 person 대상이 Employee 유형이라는 것을 안다.
이 두 종류를 없애면 TypeScript 컴파일러는 Animal 문장이 다른 두 종류를 없앴기 때문에 if 라는 것을 알 수 있다.

보호 장치 유형
기원 유형으로 구성된 연합 유형의 대상을 확정하기 위해 우리는 typeof 조작부호를 사용할 수 있다.
예를 들어, 만약 우리가 결합 형식 number | string | boolean 의 변수를 가지고 있다면, 우리는 숫자, 문자열, 부울 값인지 확인하기 위해 아래 코드를 작성할 수 있다.예를 들어,
const isNumber = (x: any): x is number =>{
    return typeof x === "number";
}
const isString = (x: any): x is string => {
    return typeof x === "string";
}
const doSomething = (x: number | string | boolean) => {
  if (isNumber(x)) {
    console.log(x.toFixed(0));
  }
  else if (isString(x)) {
    console.log(x.length);
  }
  else {
    console.log(x);
  }
}
doSomething(1);
그리고 우리는 첫 번째 if 블록에서처럼number 방법을 호출할 수 있다. 왜냐하면 우리는 isNumber 함수를 사용하여 TypeScript 컴파일러가 x가 숫자인지 확인하는 것을 돕기 때문이다.
마찬가지로 이것은 두 번째 isString 블록의 if 함수의 문자열 검사에도 적용된다.
만약 변수가 숫자도 문자열도 아니라면, 그것은 볼형으로 확정될 것이다. 왜냐하면 우리는 숫자, 문자열, 볼형의 병집합이 있기 때문이다.typeof형 보호 장치는 다음과 같은 방법으로 작성할 수 있다.
  • typeof v === "typename"
  • typeof v !== "typename"
  • 그 중에서 “typename”"number", "string", "boolean" 또는 "symbol"일 수 있다.

    Instanceof형 보호막instanceof 유형 보호는 실례 유형의 유형을 확정하는 데 사용할 수 있습니다.
    부모 유형이 파생된 하위 유형을 고려하면 대상이 어떤 하위 유형에 속하는지 확인하는 데 도움이 된다.예를 들어, 다음 코드와 같이 instanceof 유형의 보호 장치를 사용할 수 있습니다.
    interface Animal {
      kind: string;
    }
    class Dog implements Animal{
      breed: string;
      kind: string;
      constructor(kind: string, breed: string) {    
        this.kind = kind;
        this.breed = breed;
      }
    }
    class Cat implements Animal{
      age: number;
      kind: string;
      constructor(kind: string, age: number) {    
        this.kind = kind;
        this.age = age;
      }
    }
    const getRandomAnimal = () =>{
      return Math.random() < 0.5 ?
        new Cat('cat', 2) :
        new Dog('dog', 'Laborador');
    }
    let animal = getRandomAnimal();
    if (animal instanceof Cat) {
      console.log(animal.age);
    }
    if (animal instanceof Dog) {
      console.log(animal.breed);    
    }
    
    위 코드에는 getRandomAnimal 함수가 있는데, 이 함수는 Cat 또는 Dog 대상을 되돌려줍니다. 따라서 이 함수의 되돌림 유형은 Cat | Dog입니다.CatDog 모두 Animal 인터페이스를 실현했다.instanceof 유형 보호는 그 구조 함수를 통해 대상의 유형을 확정한다. CatDog 구조 함수는 서로 다른 서명을 가지고 있기 때문에 구조 함수 서명을 비교하여 유형을 확정할 수 있다.
    만약 두 종류가 같은 서명을 가지고 있다면 instanceof 유형 보호도 정확한 유형을 정하는 데 도움을 줄 것이다.if (animal instanceof Cat) { ... } 블록에서 우리는 age의 실례적인 Cat 구성원을 방문할 수 있다.
    마찬가지로 if (animal instanceof Dog) {...} 블록에서 우리는 Dog 실례적인 전유의 구성원을 방문할 수 있다.

    결론
    TypeScript 컴파일러는 다양한 유형의 보호 및 유형 술어를 사용하여 조건문을 사용하여 유형 범위를 좁힐 수 있습니다.
    유형 술어는 is 키워드로 표시된다. 예를 들어 pet is Cat 그 중에서 pet는 변수이고 Cat는 유형이다.우리는 또한 typeof 유형 보호로 기본 유형을 검사하고 instanceof 유형 보호로 실례 유형을 검사할 수 있다.
    그 밖에 우리는 in 연산자가 대상에 속성이 존재하는지 검사하는데 이것은 반대로 속성의 존재를 통해 대상의 유형을 확정한다.

    좋은 웹페이지 즐겨찾기