Ts learns assertion-guard

assertions

Type assertion:

  • You can tell the compiler by type assertion, trust me, I know what I’m doing, type assertion is like casting in other languages, but without the special data checking and deconstruction. It has no run-time impact, only at compile time. TypeScript assumes that you have done the necessary checking.

  • Type assertions come in two forms, Angle brackets and AS, which can be written as in JSX.

let someValue: any = "this is a string";

// Angle brackets

let strLength: number = (<string>someValue).length;

/ / as written

let strLength: number = (someValue as string).length;

When type assertion errors are used, the type cannot be converted, but the code can be protected from crashing

let a: any = 8;   // The variable a is inferred by type to be number

console.log(a as string);  // Outputs type 8: number

console.log((a as string).length); / / output undifined

Copy the code

Not empty assertion

  • x! Null and undefined are excluded from the x range
function myFunc(maybeNumber: number | undefined | null{

  // Type 'string | null | undefined' is not assignable to type 'string'.

  // Type 'undefined' is not assignable to type 'string'.

  const onlyNumber: number = maybeNumber; // Error

  const ignoreUndefinedAndNull: number= maybeString! ;// Ok

}



Copy the code

The maybeNumber type contains undefined and null, but with a non-null assertion, only number is left.

  • Ignore undefined when calling a function
type NumGenerator = (a)= > number;



function myFunc(numGenerator: NumGenerator | undefined{

  const num1 = numGenerator(); // Error

  constnum2 = numGenerator! (a);//OK

}

Copy the code

Summary: Non-null assertions are a mutual deception between you and the compiler that you know the function will return unreliable results, and that the compiler will cheat you that the unreliable code will work fine.

Confirm the assignment assertion

  • Tells TS that the property is explicitly assigned.
// If not used, an error will be reported when used without assigning a value

let x: number;

initialize();

// Variable 'x' is used before being assigned.(2454)

console.log(2 * x); // Error



function initialize({

  x = 10;

}

// When used, tell ts that this value will be assigned, at compile time, because of the precompile reason it will work

letx! :number;

initialize();

console.log(2 * x); // Ok



function initialize({

  x = 10;

}

Copy the code

Type guard:

A type guard is an expression that can perform runtime checks to ensure that the type is within a certain range,

  • In the keyword
interface Admin {

  name: number;

  privileges: string[];

}



interface Employee {

  name: number;

  startDate: Date;

}



type UnknownEmployee = Employee | Admin;



function printEmployeeInformation(emp: UnknownEmployee{

  console.log("Name: " + emp.name);

  if ("privileges" in emp) {

    console.log("Privileges: " + emp.privileges);

  }

  if ("startDate" in emp) {

    console.log("Start Date: " + emp.startDate);

  }

}

Copy the code

The in keyword gives you a choice. You can choose from a limited set of types. In the above example, if your value is in admin, take it from admin, and if your value is in Employee, take it from Employee

  • The typeof keyword
function padLeft(value: string, padding: string | number{

  if (typeof padding === "number") {

      return Array(padding + 1).join("") + value;

  }

  if (typeof padding === "string") {

      return padding + value;

  }

  throw new Error(`Expected string or number, got '${padding}'. `);

}

Copy the code

Typeof x===”dataType”, dataType must be “number”,”string”,” Boolean “, or symbol. Ts does not block other comparisons, but does not recognize those expressions as type-protected.

  • Instanceof keyword, my understanding is type refinement
interface Padder {

    getPaddingString(): string

}



class SpaceRepeatingPadder implements Padder {

    constructor(private numSpaces: number) {}

    getPaddingString() {

        return Array(this.numSpaces + 1).join("");

    }

}



class StringPadder implements Padder {

    constructor(private value: string) {}

    getPaddingString() {

        return this.value;

    }

}



function getRandomPadder({

    return Math.random() < 0.5 ?

        new SpaceRepeatingPadder(4) :

        new StringPadder("");

}



/ / type for SpaceRepeatingPadder | StringPadder

let padder: Padder = getRandomPadder();



if (padder instanceof SpaceRepeatingPadder) {

    padder; // Type refined to 'SpaceRepeatingPadder'

}

if (padder instanceof StringPadder) {

    padder; // Type refinement to 'StringPadder'

}

Copy the code

Summary: Padder originally had several types to choose from, but Instanceof broke it down into a few categories

  • Type predicates for custom type protection
function isNumber(x: any): x is number {

  return typeof x === "number";

}



function isString(x: any): x is string {

  return typeof x === "string";

}



Copy the code