방어

개시하다

TypeScript 추론형의 기능이 있어 조건을 나눌 때 자동으로 축소된다.이 메커니즘을 유형 방어(Type Gurd)라고 합니다.
다음은 유형을 축소하는 몇 가지 방법을 소개한다.

typeof 연산자


type of는 순수한 UNION형과 잘 어울린다.순수한 UNION형(예를 들어 리텔형과 UNION형이 아닌 복합형)에 대해서는 type of에서 피형 방어를 해야 한다는 것이다.오류가 발생했습니다.
function doSomething(x: 'max' | 7) {
  if (typeof x === 'max') { //エラー(型 '"string" | "number" | "bigint" |  "boolean" | "symbol" | "undefined" | "object" | "function"' と '"max"' には重複がないため、この条件は常に 'false' を返します。)
    console.log(x.toUpperCase());
  } else {
    console.log(x.toFixed(2));
  }
}
잘못된 내용에도 기재되어 있지만 type of는 JavaScript에서 데이터 유형을 조사하기 때문에 TypeScript에 대응하는 소양형의 조건 지점에 대응할 수 없다.
따라서 다음과 같은 순수한 연합형(이곳은number형이나string형)은 type of를 사용한다.
//型ガードfunction doSomething(x: number | string) {
  if (typeof x === "string") {
    console.log(x.toUpperCase());
  } else {
    console.log(x.toFixed(2));
  }
}
doSomething('max')//MAX
doSomething(7)//7.00
상기 함수는number나string을 매개 변수로 받아들인다.
x일 때는 유니온형이라 어느 쪽인지 판단이 안 돼요.
그러나if문은 x의 typeof를 검사했고if 블록에서 x는string으로 확정되었습니다.그리고 TypeScript 그걸 알아요. x는string 자동 추론이에요.그리고else 블록에서 x가string이 아니라는 사실이 확인되어 형식이 축소되었기 때문에number로 추정됩니다.

in 연산자

JavaScript에는 in이라는 키워드가 있다.in을 사용하여 객체의 등록 정보를 확인할 수 있습니다.
다음은 인터페이스를 사용하는 유형 보호입니다.
interface Person {
  name: string;
  age: number;
}
interface Book {
  name: string;
  price: number;
}

//型ガード
function doStuff(arg: Person | Book) {
  if ("age" in arg) {//ageプロパティはPersonのみ存在(Bookにはない)
    console.log(arg.name);
  } else {
    console.log(arg.price);
  }
}
doStuff({ name: "max", age: 22 });
doStuff({ name: "チャート式", age: 2000 });

instanceof


클래스를 사용하면 형식 보호를 표시하기 위해 "instanceof"연산자를 사용할 수 있습니다.
class Car {
  drive() {
    console.log("運転中...");
  }
}
class Truck {
  drive() {
    console.log("トラックを運転中");
  }
  lpadCargo(amount: number) {
    console.log("荷物を載せています" + amount);
  }
}
const v1 = new Car();
const v2 = new Truck();

//型ガード
function useVehicle(vehicle: Car | Truck) {
  vehicle.drive();
  if (vehicle instanceof Truck) {
    vehicle.lpadCargo(1000);
  }
}
useVehicle(v1);//運転中...
useVehicle(v2);//トラックを運転中
               //荷物を載せています1000
이 instanceof 연산자는 JavaScript에 포함됩니다.JavaScript Truck의 유형은 모르지만 cons tructor 함수나 클래스로서의 Truck을 알고 있습니다.
따라서 JavaScriptinstanceof를 통해 Truck이라는 구조기 함수에 따라 만들어진 대상인지 판단할 수 있다.

여기까지의 형 방어의 문제점.


지금까지 typeof, in, instanceof가 사용하는 유형 보호의 예를 보았지만, 유형 축소에 대한 공통된 문제점이 있습니다.
이것은 현재 범위 내에서 변수를 축소하는 위력에 불과하다.그 범위를 벗어나면 유형의 축소는 새로운 범위에 계승될 수 없다.
다음 코드로 확인하세요.
function doSomething(x: number | string) {
  const isString = (x: number | string) => typeof x === "string";
  if (isString(x)) {
    console.log(x.toUpperCase());//エラー(プロパティ 'toUpperCase' は型 'string | number' に存在しません。)
  } else {
    console.log(x.toFixed(2));
  }
}
type 연산자 중의 코드를 조금 만들었습니다.
조건 브랜치에서 typeof를 사용하는 곳에 isString이라는 변수에 저장한 다음 조건 브랜치에서string형을 축소합니다.
그러나 x형은string형(파라미터형으로 정의된number형이나string형의 연합형)으로 축소할 수 없으며,string 특유의 방법을 사용하면 욕을 먹을 수 있다.
이렇게 하면 역할 영역을 벗어나면 (isString 변수에 저장됨) 유형 보호 기능이 좋지 않습니다.

사용자 정의 보호


is 연산자를 사용하면 조건식(작용역에서 벗어나는)을 잘라낼 수 있습니다.is 연산자는 개발자가 Type Script에 대해 가르치는 기능으로, 사용자정의 보호라고 불린다.함수 반환 값이 매개변수 X is T와 연관된 경우 조건이 진짜로 반환되면 X는 T이고 거짓으로 반환된 경우 T가 아닌 것을 나타냅니다TypeScript.

typeof 및 사용자 정의 보호


function doSomething(x: number | string) {
  const isString = (x: number | string): x is string => typeof x === "string";
  if (isString(x)) {
    console.log(x.toUpperCase());
  } else {
    console.log(x.toFixed(2));
  }
}
doSomething("max"); //MAX
isString은 반환 값을 x is number와 연결하기 때문에 진짜로 반환하면 arg가number라고 생각합니다.따라서if 블록의 x는string으로 축소됩니다.
이 기능을 사용하면 유형 보호를 함수로 잘라낼 수도 있고 복잡한 유형 보호를 실현할 수도 있다.
//is演算子による型ガードconst isString = (arg: number | string): arg is string => typeof x === "string";
function doSomething(x: number | string) {
  if (isString(x)) {
    console.log(x.toUpperCase());
  } else {
    console.log(x.toFixed(2));
  }
}
doSomething("max"); //MAX

in 연산자 및 사용자 정의 보호


interface Person {
  name: string;
  age: number;
}
interface Book {
  name: string;
  price: number;
}
//is演算子による型ガード
const isPerson = (arg: Person | Book): arg is Person => "age" in arg;
const doStuff = (x: Person | Book) => {
  if (isPerson(x)) {
    console.log(x.age);
  } else {
    console.log(x.price);
  }
};
doStuff({ name: "max", age: 22 });
doStuff({ name: "チャート式", price: 2000 });

instanceof 연산자와 사용자 정의 보호


class Car {
  drive() {
    console.log("運転中...");
  }
}
class Truck {
  drive() {
    console.log("トラックを運転中");
  }
  lpadCargo(amount: number) {
    console.log("荷物を載せています" + amount);
  }
}
const v1 = new Car();
const v2 = new Truck();

//is演算子による型ガード
const isTruck = (arg: Car | Truck): arg is Truck => arg instanceof Truck;
function useVehicle(vehicle: Car | Truck) {
  vehicle.drive();
  if (isTruck(vehicle)) {
    vehicle.lpadCargo(1000);
  }
}
useVehicle(v1); //運転中...
useVehicle(v2); //トラックを運転中
//荷物を載せています1000

좋은 웹페이지 즐겨찾기