TypeScript积累

TypeScript

  • 使用无效合并运算符引发内联误差

    很多时候,如果特定值为 null 或未定义,我们发现自己需要抛出错误。TypeScript 提供了一种使用空合并运算符 (??) 和简单的帮助程序函数来内联此过程的方法,而不是手动检查。

    const raise = (err: string) : never => { throw new Error(err);};
    

    这个“raise”函数与 nullish 合并运算符结合使用时,允许您编写更具可读性和简洁的代码。

    const Page = (props: { params: { id?: string }}) => {
      const id = props.params.id ?? raise('No id provided');
    };
    
    注:never

    在 TypeScript 中,never 是一个表示永远不会发生的类型。它表示一个函数永远不会返回任何值,或者一个函数抛出一个异常。

raise 是一个函数,它接受一个字符串参数 err,并且返回类型被声明为 never。这意味着当调用 raise 函数时,它会抛出一个错误并终止程序的执行,而不会返回任何值。

使用 never 类型可以用于以下几种情况:

  1. 抛出异常:当函数遇到错误或不可恢复的情况时,可以使用 never 类型来表示函数会抛出一个异常并终止程序的执行。
function throwError(message: string): never {
  throw new Error(message);
}

throwError("Something went wrong!"); // 抛出错误并终止程序的执行
  1. 无限循环:当函数进入一个无限循环时,可以使用 never 类型来表示函数永远不会返回。
function infiniteLoop(): never {
  while (true) {
    // 无限循环
  }
}

infiniteLoop(); // 永远不会返回
  1. 类型推断:当 TypeScript 无法推断出函数的返回类型时,可以使用 never 类型来明确指定函数永远不会返回。
function unreachableCode(): never {
  return 42; // 错误:返回类型不匹配
}

总结:never 类型表示一个函数永远不会返回任何值或抛出异常。它在处理错误、无限循环或指定函数的返回类型时非常有用。

  • 利用映射类型

    映射类型是一个强大的 TypeScript 功能,允许您基于现有类型创建新类型。它们可以帮助您保持类型干燥,减少重复并提高可维护性。

    • Readonly

      interface IUser {
        name: string;
        age: number;
      }
      
      type ReadonlyUser = Readonly<IUser>;
      

      现在,ReadonlyUser类型的队形 的所有属性都是只读的。

    • Partial

      type PartialUser = Partial<IUser>;
      

      PartialUser 现在是 { name?: string, age?: number }

    • Record

      映射类型可用于创建属性键所在的对象类型,属性值为 :Record<K,T> K T

      type UserRecord = Record<string, IUser>;
      

      UserRecord现在是一个对象类型,它将接受任何字符串作为键,并且任何值都必须是 类型。IUser

      创建自己的映射类型

      您不仅限于 TypeScript 提供的映射类型。您还可以创建自己的:

      type Nullable<T> = { [P in keyof T]: T[P] | null };
      

      此类型采用现有类型,并生成一个新类型,其中每个属性都可为空。Nullable<T>``T

      映射类型可帮助您基于现有类型创建复杂类型,从而减少代码重复并增强类型安全性。

      注: Ts中 keyof 关键字的使用

      keyof 是 TypeScript 中的一个关键字,用于获取一个类型的所有键的联合类型。它可以用于获取一个对象类型的所有键,也可以用于获取一个联合类型的所有共有键。

      例如,假设有一个对象类型:

      type Person = {
        name: string;
        age: number;
        gender: string;
      };
      

      可以使用 keyof 来获取该类型的所有键:

      type PersonKeys = keyof Person;
      // PersonKeys 的类型为 "name" | "age" | "gender"
      

      同样,keyof 也可以用于获取一个联合类型的所有共有键。例如:

      type Animal = {
        name: string;
        age: number;
      };
      
      type Plant = {
        name: string;
        color: string;
      };
      
      type Organism = Animal | Plant;
      
      type OrganismKeys = keyof Organism;
      // OrganismKeys 的类型为 "name"
      

      在这个例子中,联合类型 Organism 中只有 name 这个键是共有的,所以 OrganismKeys 的类型只包含 “name”。

      注:Ts 中 in关键字的作用

      在 TypeScript 中,in 是一个关键字,用于判断一个属性是否存在于一个对象或者类型中。

      它可以用在两个不同的场景中:

      1. 在类型保护中使用:可以使用 in 操作符来检查一个属性是否存在于一个对象中,从而进行类型保护。例如:
      interface Person {
        name: string;
        age?: number;
      }
      
      function printPersonInfo(person: Person) {
        if ('age' in person) {
          console.log(`${person.name} is ${person.age} years old.`);
        } else {
          console.log(`${person.name} has no age specified.`);
        }
      }
      
      const person1: Person = {
        name: 'John',
        age: 25,
      };
      
      const person2: Person = {
        name: 'Alice',
      };
      
      printPersonInfo(person1); // Output: John is 25 years old.
      printPersonInfo(person2); // Output: Alice has no age specified.
      

      在上面的例子中,我们使用 in 操作符来检查 person 对象是否具有 age 属性。如果有,就打印年龄信息;如果没有,就打印没有指定年龄的信息。

      1. 在 for…in 循环中使用:可以使用 in 操作符来迭代一个对象的所有属性。例如:
      interface Person {
        name: string;
        age: number;
        gender: string;
      }
      
      const person: Person = {
        name: 'John',
        age: 25,
        gender: 'male',
      };
      
      for (const key in person) {
        console.log(`${key}: ${person[key]}`);
      }
      
      // Output:
      // name: John
      // age: 25
      // gender: male
      

      在上面的例子中,我们使用 for…in 循环来迭代 person 对象的所有属性,并打印每个属性的键和对应的值。

      总结:in 关键字在 TypeScript 中用于判断属性是否存在于一个对象或类型中,并在类型保护和循环迭代中发挥作用.

  • 类型防护

    TypeScript 支持用户定义的类型保护,以缩小条件块中对象的类型。这是通过使用返回布尔值的函数来实现的,该函数指示对象是否属于特定类型。

    function isString(test: any): test is string {
      return typeof test === "string";
    }
    
    function printLength(input: string | any[]) {
      if (isString(input)) {
        console.log(input.length);
      } else {
        console.log(input.length);
      }
    }
    

    在此示例中,是一个类型保护,可确保在 if 块中被视为字符串。isString``input

    注:类型谓词的用法
    类型谓词的语法是 parameterName is Type,其中 parameterName 是函数参数的名称,Type 是要判断的类型。当函数返回值为布尔类型时,test is string 表示如果 test 是一个字符串类型,则返回 true,否则返回 false

    以下是一些更多的例子,展示了如何使用类型谓词来进行类型保护:

    function isNumber(test: any): test is number {
      return typeof test === "number";
    }
    
    function isObject(test: any): test is object {
      return typeof test === "object" && test !== null;
    }
    
    function isBoolean(test: any): test is boolean {
      return typeof test === "boolean";
    }
    
    function isUndefined(test: any): test is undefined {
      return typeof test === "undefined";
    }
    
    interface Person {
      name: string;
      age: number;
    }
    
    function isPerson(test: any): test is Person {
      return typeof test === "object" && test !== null && "name" in test && "age" in test;
    }
    

    在上面的例子中,我们定义了一些类型谓词函数,用于判断不同的类型。例如,isNumber 函数判断一个值是否为数字类型,isObject 函数判断一个值是否为对象类型,isPerson 函数判断一个值是否为 Person 类型。

    这些类型谓词函数可以在类型保护中使用,以便在代码中进行类型推断和类型检查。例如:

    function printValue(value: any) {
      if (isString(value)) {
        console.log(value.toUpperCase());
      } else if (isNumber(value)) {
        console.log(value.toFixed(2));
      } else if (isObject(value)) {
        console.log(Object.keys(value));
      }
    }
    
    printValue("hello"); // Output: HELLO
    printValue(3.14159); // Output: 3.14
    printValue({ name: "John", age: 25 }); // Output: [ 'name', 'age' ]
    

    在上面的例子中,printValue 函数接受一个参数 value,并根据不同的类型进行不同的处理。使用类型谓词函数可以在调用 printValue 函数时进行类型保护,以确保在处理 value 时能够正确推断其类型。

  • 强制实施只读属性
    TypeScript 具有修饰符,可以轻松创建设置后无法更改的属性。这对于创建具有不应更改的属性的对象特别有用。readonly
    interface Config {
      readonly apiUrl: string;
      readonly defaultTimeout: number;
    }
    
    const config: Config = {
      apiUrl: "https://myapi.com",
      defaultTimeout: 5000,
    };
    
    config.apiUrl = "https://anotherapi.com"; // Error!
    

    在此示例中,任何更改 或 的尝试都将导致 TypeScript 错误。apiUrl``defaultTimeout

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值