TS高级开发技巧15条

news2025/2/2 16:08:49

TS高级开发技巧15条

image.png image.png image.png

1.可选链 Optional Chaining (?.):
在不用担心遇到 null 或 undefined 值的前提下,可选链允许你安全访问 nested 对象属性和方法。 他会简单计算类型为 null 或者 undefined 的中间属性。

const user = {
  name: 'John',
  address: {
    city: 'New York',
    postalCode: '12345'
  }
};


const postalCode = user.address?.postalCode;
console.log(postalCode); // Output: 12345

const invalidCode = user.address?.postalCode?.toLowerCase();
console.log(invalidCode); // Output: undefined

2.无效合并操作符 (??):
当变量为 null 或 undefined 时为新变量提供一个默认值

    const name = null;
    const defaultName = name ?? 'Unknown';
    console.log(defaultName); // Output: Unknown

    const age = 0;
    const defaultAge = age ?? 18;
    console.log(defaultAge); // Output: 0

3.类型断言:
当ts无法推断一个变量类型的时候,类型断言允许你显式定义一个变量的类型

    const userInput: unknown = 'Hello World';
    const strLength = (userInput as string).length;
    console.log(strLength); // Output: 11

4.泛型:
泛型能够让你创建可与多种类型一起使用的可重用组件。

// 使用 Generics 的函数示例
function identity<T>(arg: T): T {
  return arg;
}

let result = identity<string>("Hello, TypeScript!"); // 类型参数为 string
console.log(result); // 输出:Hello, TypeScript!

let anotherResult = identity<number>(42); // 类型参数为 number
console.log(anotherResult); // 输出:42

// 使用 Generics 的类示例
class Container<T> {
  private value: T;

  constructor(value: T) {
    this.value = value;
  }

  getValue(): T {
    return this.value;
  }
}

let container = new Container<number>(42); // 类型参数为 number
console.log(container.getValue()); // 输出:42

5.keyof 操作符:
keyof 操作符会返回一个类型所有已知属性的联合类型

interface Person {
  name: string;
  age: number;
  location: string;
}

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

6.类型保护:
类型保护用于在编写代码时判断变量的类型,并在特定条件下缩小变量的类型范围

    function logMessage(message: string | number) {
      if (typeof message === 'string') {
        console.log('Message: ' + message.toUpperCase());
      } else {
        console.log('Value: ' + message.toFixed(2));
      }
    }

    logMessage('hello'); // Output: Message: HELLO
    logMessage(3.14159); // Output: Value: 3.14

7.交叉类型:
通过使用交叉类型,我们可以将多个类型合并为一个类型,以获得所有类型的联合。这意味着新类型将具备所有交叉类型中的属性和方法,并且可以在代码中使用这些属性和方法。

interface A {
  propA: string;
  methodA(): void;
}

interface B {
  propB: number;
  methodB(): void;
}

type AB = A & B;

const obj: AB = {
  propA: "Hello",
  propB: 42,
  methodA() {
    console.log("Method A");
  },
  methodB() {
    console.log("Method B");
  }
};

8.映射类型:
是一种用于从现有类型创建新类型的机制。它允许我们基于现有类型的属性进行转换和修改,从而生成具有相似结构但具有不同类型或属性修饰符的新类型。

TypeScript提供了几种Mapped Types的内置形式,包括:

  1. Partial: 将类型T的所有属性变为可选属性。
  2. Readonly: 将类型T的所有属性变为只读属性。
  3. Required: 将类型T的所有可选属性变为必需属性。
  4. Pick<T, K>: 从类型T中选择指定属性K组成新类型。
  5. Omit<T, K>: 从类型T中排除指定属性K组成新类型。
  6. Record<K, T>: 创建一个包含属性K和对应类型为T的新类型。
interface Person {
  name: string;
  age: number;
}

type PartialPerson = Partial<Person>;
// 等同于 { name?: string; age?: number; }

type ReadonlyPerson = Readonly<Person>;
// 等同于 { readonly name: string; readonly age: number; }

type RequiredPerson = Required<Person>;
// 等同于 { name: string; age: number; }

type PickName = Pick<Person, 'name'>;
// 等同于 { name: string; }

type OmitAge = Omit<Person, 'age'>;
// 等同于 { name: string; }

type RecordExample = Record<'id' | 'name', number>;
// 等同于 { id: number; name: number; }

9. 字符串字面量类型 和 联合类型 :
字符串字面量类型是指将特定字符串直接作为类型的一部分,而不仅仅是字符串值。通过使用字符串字面量类型,我们可以将变量或参数的类型限定为特定的字符串取值之一.

type Color = "red" | "green" | "blue";
let color: Color;

color = "red";    // 合法
color = "green";  // 合法
color = "yellow"; // 不合法,不是 Color 类型的取值之一

联合类型是指将多个类型组合成一个类型的能力。通过使用联合类型,我们可以指定变量或参数的类型可以是多个类型之一

type MyNumber = number | string;
let value: MyNumber;

value = 10;       // 合法
value = "Hello";  // 合法
value = true;     // 不合法,不是 MyNumber 类型的取值之一

10.装饰器:
用于添加元数据和修改类、方法、属性等声明的特殊语法。装饰器提供了一种简洁的方式来扩展和修改现有的代码,以实现元编程的能力。

    function uppercase(target: any, propertyKey: string) {
      let value = target[propertyKey];

      const getter = () => value;
      const setter = (newValue: string) => {
        value = newValue.toUpperCase();
      };

      Object.defineProperty(target, propertyKey, {
        get: getter,
        set: setter,
        enumerable: true,
        configurable: true
      });
    }

    class Person {
      @uppercase
      name: string;
    }

    const person = new Person();
    person.name = 'John Doe';
    console.log(person.name); // Output: JOHN DOE

11.索引签名:
是 TypeScript 中用于描述对象的动态属性的一种方式。它允许我们定义对象的属性,其名称不是提前定义的,而是根据运行时的索引值动态确定。

interface MyObject {
  [index: string]: number;
}
    
const obj: MyObject = {
  age: 25,
  score: 90,
};

console.log(obj.age);   // 输出:25
console.log(obj.score); // 输出:90

12.带有条件语句的类型推断:
在条件语句中根据代码逻辑进行类型推断的能力。当条件语句中包含逻辑分支,每个分支都有不同的代码路径时,TypeScript 可以根据条件的真假情况推断出变量的类型。

function processValue(value: string | number) {
  if (typeof value === "string") {
    // 在此分支中,value 的类型被推断为 string
    console.log(value.length);
  } else {
    // 在此分支中,value 的类型被推断为 number
    console.log(value.toFixed(2));
  }
}

13.只读属性:
用于指定对象属性为只读的特性。一旦属性被标记为只读,就不能再修改该属性的值。

interface Person {
  readonly name: string;
  readonly age: number;
}

const person: Person = {
  name: "Alice",
  age: 30,
};

person.name = "Bob"; // 错误!无法修改只读属性

14.类型别名:
用于给现有类型创建一个新名字的特性。它允许我们为复杂或冗长的类型定义创建一个简洁、可重用的名称,以提高代码的可读性和可维护性。

    type Point = {
      x: number;
      y: number;
    };

    type Shape = 'circle' | 'square' | 'triangle';

    function draw(shape: Shape, position: Point) {
      console.log(`Drawing a ${shape} at (${position.x}, ${position.y})`);
    }

    const startPoint: Point = { x: 10, y: 20 };
    draw('circle', startPoint); // Output: Drawing a circle at (10, 20)

15.类中的类型守护:
TypeScript 中使用类型守卫来确定类实例的具体类型。

class Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  sound(): void {
    console.log("The animal makes a sound.");
  }
}

class Cat extends Animal {
  meow(): void {
    console.log("Meow!");
  }
}

class Dog extends Animal {
  bark(): void {
    console.log("Woof!");
  }
}

function makeSound(animal: Animal): void {
  animal.sound();

  if (animal instanceof Cat) {
    animal.meow(); // 类型守卫:animal 的类型被确定为 Cat
  } else if (animal instanceof Dog) {
    animal.bark(); // 类型守卫:animal 的类型被确定为 Dog
  }
}

const cat = new Cat("Whiskers");
const dog = new Dog("Buddy");

makeSound(cat); // 输出:The animal makes a sound. Meow!
makeSound(dog); // 输出:The animal makes a sound. Woof!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/762455.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】STL | 模拟实现简易string

目录 1. 框架搭建 2. 迭代器的实现 3. string的拷贝构造和赋值&#xff08;深拷贝&#xff09; 拷贝构造 赋值构造 4. string的增删查改 reserve 接口 resize 接口 push_back 接口 append 接口 operator() 实现 insert 接口 erase 接口 find 接口 substr 接口 cle…

若依前端使用图标

图标 前后端分离的若依前端使用的图标分为两种&#xff1a;分别是svg图标和element的图标 svg图标 1&#xff0c;使用方法 <!-- icon-class 为 icon 的名字; class-name 为 icon 自定义 class--> <svg-icon icon-class"password" class-namecustom-cla…

C++ for Reverse Words in a String

这道题是Leetcode上的151.反转字符串中的单词这道题&#xff0c;这道题给出的题目要求是&#xff1a; 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒…

Pycharm--Low Memory

Low Memory The IDE is running low on memory and this might affect performance. Please consider increasing available heap. 卡成翔 -- 已经配置成4096了啊

【UE4 塔防游戏系列】07-子弹对敌人造成伤害

目录 效果 步骤 一、让子弹拥有不同伤害 二、敌人拥有不同血量 三、修改“BP_TowerBase”逻辑 四、发射的子弹对敌人造成伤害 效果 步骤 一、让子弹拥有不同伤害 为了让每一种子弹拥有不同的伤害值&#xff0c;打开“TotalBulletsCategory”&#xff08;所有子弹的父类…

java线上故障排查套路总结

线上故障主要会包括cpu、磁盘、内存以及网络问题&#xff0c;而大多数故障可能会包含不止一个层面的问题&#xff0c;所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题的&#xff0c;基本上出问题就是df、free、top 三连&#x…

(五)Flask之深入剖析路由源码

路由&#xff08;Route&#xff09;这个概念在所有web框架中都非常重要&#xff0c;它是用于定义URL和对应的处理函数&#xff08;视图&#xff09;之间的映射关系。通过定义路由&#xff0c;可以使web框架应用程序能够响应不同的URL请求&#xff0c;并执行相应的逻辑。 源码剖…

老码农的管理拙见

【引子】 尽管自己从业了20多年&#xff0c;也曾管理过从几个人到几百人的团队&#xff0c;但个人非常不愿意或者不敢讨论团队管理的问题&#xff0c;因为管理是以结果为导向的&#xff0c; 具有后验的特征&#xff0c;而且管理中面对的最大复杂性是人&#xff0c;每个人都是不…

安装pycocotools报错“fatal error: Python.h: No such file or directory“ | 已解决

记录一段报错&#xff1a; pycocotools/_mask.c:6:10: fatal error: Python.h: No such file or directory#include "Python.h"^~~~~~~~~~compilation terminated./tmp/pip-build-env-crtws8v6/overlay/lib/python3.8/site-packages/Cython/Compiler/Main.py:369: F…

mssql 以xml类型为存储过程传递不确定数量的参数

mssql 以xml类型传递不确定数量的参数 存储过程xml 处理在存储过程中参数在存储过程中使用 xml 作为参数存储过程 相信各位小伙伴在使用数据库的过程中,或多或少的建立了一些存储过程,并且带有一些参数,用来增加存储过程的适用性。 类似老顾的截图这样的,通常,我们需要将…

华为云CodeArts Check IDE插件体验之旅

1 开发者的思考 近年来&#xff0c;ChatGPT的来临像一场突然出现的风暴&#xff0c;程序员是否马上被取代的担忧出现在媒体上了&#xff0c;作为软件开发小白&#xff0c;前不久我也陷入了这样的深思之中&#xff0c;但认真的想了下&#xff0c;ChatGPT就如自动驾驶一样&#…

MySQL的安装与配置

今天要和大家唠唠关于数据库的那些事儿&#xff01;按照加哥一贯的调性&#xff0c;咱还是从花边八卦聊起。先来简 单地梳理一下数据库、MySQL发展的时间线&#xff1a; 1970年&#xff0c;在IBM公司工作的数学家 E.F.Codd 发表了数学论文《大型共享数据库的关系数据模型》 &am…

每日站会如此简单,为什么总是开不好?

美式足球或橄榄球等运动的球队&#xff0c;会在每场比赛上场前聚在一起开个短会。这种临场短会能让整个球队的成员在比赛过程中互通信息、相互协作。 每日站会是敏捷开发的重要流程之一。对于团队而言&#xff0c;每日站会与这种赛前短会类似&#xff0c;让每个成员都了解到团…

2023年上海/成都/深圳CSPM-3中级国标项目管理认证招生

CSPM-3中级项目管理专业人员认证&#xff0c;是中国标准化协会&#xff08;全国项目管理标准化技术委员会秘书处&#xff09;&#xff0c;面向社会开展项目管理专业人员能力的等级证书。旨在构建多层次从业人员培养培训体系&#xff0c;建立健全人才职业能力评价和激励机制的要…

Matplotlib坐标轴范围

Matplotlib 可以根据自变量与因变量的取值范围&#xff0c;自动设置 x 轴与 y 轴的数值大小。当然&#xff0c;您也可以用自定义的方式&#xff0c;通过 set_xlim() 和 set_ylim() 对 x、y 轴的数值范围进行设置。 当对 3D 图像进行设置的时&#xff0c;会增加一个 z 轴&#x…

日志收集工具

日志管理的第一步是收集日志数据。日志收集可能是一项具有挑战性的任务&#xff0c;因为某些系统&#xff08;如防火墙、入侵检测系统和入侵防御系统&#xff09;具有生成大量日志数据的 EPS&#xff08;每秒事件数&#xff09;。为了实时收集和处理日志数据&#xff0c;无论日…

【历史上的今天】6 月 7 日:图灵逝世;Kubernetes 开源版本发布;分组交换网络发明者出生

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 6 月 7 日&#xff0c;在 1742 年的今天&#xff0c;普鲁士数学家克里斯蒂安哥德巴赫在写给瑞士数学家莱昂哈德欧拉的通信中&#xff0c;提出了以下的猜想&…

手机APP三维建模不清晰?单反相机接入移动端来袭!

为什么我们需要单反相机接入 当前&#xff0c;手机本身的像素还满足不了考古级的精度要求&#xff0c;考古现场都是用专业相机对文物进行拍照&#xff0c;再把照片导入到电脑进行建模。“考古工作比较细致&#xff0c;有时候一来一回挺费事的。”云端地球的忠实用户&#xff0…

Linux5.16 Ceph集群

文章目录 计算机系统5G云计算第四章 LINUX Ceph集群一、Ceph1.存储基础1&#xff09;单机存储设备2&#xff09;单机存储的问题3&#xff09;商业存储解决方案4&#xff09;分布式存储&#xff08;软件定义的存储 SDS&#xff09;5&#xff09;分布式存储的类型 2.Ceph 简介3.C…

微信公众号登录

整个流程&#xff0c;1.前端调用授权url 接口(创建一个重定向的请求方法&#xff0c;访问自动回调方法wechat.mp.callbackUrl的地址)。2.微信自动回调方法里判断该用户是需要注册还是直接登录(如果直接登录就返回token&#xff09; 是注册还是登录返回到配置文件中的 wechat.mp…