TypeScript使用技巧

简介: TypeScript使用技巧

原文合集地址如下,有需要的朋友可以关注

本文地址

@[TOC]
TypeScript作为JavaScript的超集,通过提供静态类型系统和对ES6+新特性的支持,使JavaScript开发变得更加高效和可维护。掌握TypeScript的使用技巧,可以帮助我们更好地开发和组织JavaScript项目。刚开始用的时候感觉好多限制,特别是配置静态类型检测后就容易各种报错,恨不得都用any, 那岂不是成了AnyScript,不过熟能生巧,用得多了就会爱上这个语言。这里总结了一些平时用到ts技巧。

使用技巧

当使用TypeScript进行开发时,有一些常用的技巧可以帮助你提高代码质量和开发效率。以下是一些TypeScript使用技巧:

  1. 类型注解和类型推断:尽量为变量、函数参数、函数返回值等添加类型注解,以增加代码的可读性和类型安全性。同时,TypeScript也会自动推断很多类型,充分利用类型推断特性。

  2. 使用接口和类型别名:使用接口和类型别名来定义自定义类型,使代码更具表达力和清晰度。

// 使用接口
interface Person {
   
  name: string;
  age: number;
}

// 使用类型别名
type Point = {
    x: number; y: number };
  1. 泛型:使用泛型来增加代码的灵活性,使函数和类能够处理多种类型的数据。
function toArray<T>(value: T): T[] {
   
  return [value];
}
  1. 枚举:使用枚举来定义一组具有名字的常量值,提高代码可读性。
enum Color {
   
  Red,
  Green,
  Blue,
}
  1. 非空断言和可选链:使用非空断言(!)来告诉编译器一个值一定不为null或undefined,使用可选链(?.)来简化处理可能为null或undefined的属性和方法。
const name: string = maybeName!; // 非空断言
const age = person?.age; // 可选链
  1. 确定赋值断言:在声明变量时使用确定赋值断言(!)来告诉编译器该变量一定会在使用前被赋值。
let value!: number;

TypeScript内置的工具类型

当使用 TypeScript 进行开发时,有一些常用的类型工具(utility types)可以帮助你更好地处理类型,并提高代码质量和开发效率。下面是对 PartialRecordPickOmitExcludeParameters 这些类型工具的中文详细解释:

  1. Partial<Type>(部分类型):

    • Partial 是 TypeScript 内置的一个类型工具,用于使给定类型的所有属性变为可选属性。
    • 它创建了一个新的类型,其中给定类型 Type 的所有属性都变成了可选属性。
    • 示例:
      ```typescript
      interface Person {
      name: string;
      age: number;
      }

    type PartialPerson = Partial;

    // 等同于:
    // interface PartialPerson {
    // name?: string;
    // age?: number;
    // }
    ```

  2. Record<Key, Type>(记录类型):

    • Record 是 TypeScript 内置的类型工具,用于创建一个由指定键和给定值类型组成的对象类型。
    • 它接受两个类型参数 KeyType,并创建一个对象类型,其中每个属性的键是类型 Key,值是类型 Type
    • 示例:
      ```typescript
      type AgeMap = Record;

    // 等同于:
    // interface AgeMap {
    // [key: string]: number;
    // }
    ```

  3. Pick<Type, Keys>(挑选类型):

    • Pick 是 TypeScript 内置的类型工具,用于从给定类型中挑选出特定的属性形成新的类型。
    • 它接受两个类型参数 TypeKeys,并创建一个新的类型,其中只包含类型 Type 中由 Keys 指定的属性。
    • 示例:
      ```typescript
      interface Person {
      name: string;
      age: number;
      address: string;
      }

    type PersonNameAndAge = Pick;

    // 等同于:
    // interface PersonNameAndAge {
    // name: string;
    // age: number;
    // }
    ```

  4. Omit<Type, Keys>(省略类型):

    • Omit 是 TypeScript 内置的类型工具,用于从给定类型中省略特定的属性形成新的类型。
    • 它接受两个类型参数 TypeKeys,并创建一个新的类型,其中包含了类型 Type 中除了 Keys 指定的属性以外的所有属性。
    • 示例:
      ```typescript
      interface Person {
      name: string;
      age: number;
      address: string;
      }

    type PersonWithoutAddress = Omit;

    // 等同于:
    // interface PersonWithoutAddress {
    // name: string;
    // age: number;
    // }
    ```

  5. Exclude<Type, ExcludedUnion>(排除类型):

    • Exclude 是 TypeScript 内置的类型工具,用于从给定类型中排除可以赋值给 ExcludedUnion 的成员。
    • 它接受两个类型参数 TypeExcludedUnion,并创建一个新的类型,其中只包含类型 Type 中不可赋值给 ExcludedUnion 的成员。
    • 示例:
      ```typescript
      type MyNumbers = number | string | boolean;

    type OnlyNumbers = Exclude;

    // 等同于:
    // type OnlyNumbers = number;
    ```

  6. Parameters<Type>(函数参数类型):

    • Parameters 是 TypeScript 内置的类型工具,用于从给定函数类型中提取出参数的类型。
    • 它接受一个函数类型 Type 作为参数,并返回一个由该函数的参数类型组成的元组类型。
    • 示例:
      ```typescript
      type MyFunction = (name: string, age: number) => void;

    type FunctionParameters = Parameters;

    // 等同于:
    // type FunctionParameters = [string, number];
    ```

keyof

在 TypeScript 中,keyof 是一个关键字和类型操作符,它用于获取一个类型的所有属性名组成的联合类型。keyof 可以结合泛型、索引类型等特性来实现许多有用的类型操作。

使用 keyof 的语法是 keyof Type,其中 Type 是一个类型。它返回一个联合类型,包含了 Type 类型中所有属性的名称。这个联合类型可以用来访问或操作 Type 类型中的属性。keyof 与 Object.keys 略有相似,只不过 keyof 取 interface 的键。

下面是一个简单的示例代码:

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

type PersonKey = keyof Person;
// 等同于:type PersonKey = "name" | "age" | "gender"

在这个例子中,keyof Person 返回一个联合类型,包含了 Person 类型中所有属性的名称。结果类型是 "name" | "age" | "gender"

keyof 可以与其他 TypeScript 特性结合使用,例如:

  1. 通过索引类型访问对象属性:
function getProperty<T, K extends keyof T>(obj: T, key: K) {
   
  return obj[key];
}

const person: Person = {
    name: "Alice", age: 30, gender: "female" };
const name = getProperty(person, "name"); // name的类型是string
  1. 确定属性是否存在:
function hasProperty<T, K extends keyof T>(obj: T, key: K): boolean {
   
  return key in obj;
}

const hasAge = hasProperty(person, "age"); // hasAge的值是true
const hasEmail = hasProperty(person, "email"); // hasEmail的值是false

extends 限定泛型

在 TypeScript 中,可以使用 extends 关键字来限定泛型类型的范围,确保传入的泛型参数满足一定的条件。这种方式称为"泛型约束"或"泛型限定"。通过泛型约束,我们可以对泛型进行更精确的类型检查,提高代码的类型安全性。

下面是几个使用 extends 关键字限定泛型的例子:

  1. 简单的泛型约束:
function printProperty<T extends {
    name: string }>(obj: T) {
   
  console.log(obj.name);
}

printProperty({
    name: "Alice", age: 30 }); // OK
printProperty({
    age: 30 }); // Error: 缺少name属性

在这个例子中,使用 extends { name: string } 来限定泛型 T 必须具有一个 name 属性,否则会在调用时报错。

  1. 使用多个泛型约束:
function combine<T extends string, U extends string>(a: T, b: U): string {
   
  return a + b;
}

const result = combine("Hello, ", "TypeScript"); // result的值是 "Hello, TypeScript"

在这个例子中,使用 extends string 来限定泛型 TU 必须是 string 类型,确保只有 string 类型的参数可以传入函数 combine 中。

  1. 使用接口约束泛型:
interface Lengthwise {
   
  length: number;
}

function printLength<T extends Lengthwise>(obj: T) {
   
  console.log(obj.length);
}

printLength("Hello"); // 输出: 5
printLength([1, 2, 3]); // 输出: 3

在这个例子中,使用 extends Lengthwise 来限定泛型 T 必须满足 Lengthwise 接口,即必须有一个 length 属性。

interface 与 type 区别

在 TypeScript 中,interfacetype 是两种用来定义类型的方式,它们有一些相似之处,但也有一些不同之处。下面是它们的区别:

  1. interface

    • interface 是用来描述对象的形状的类型声明。
    • 它可以用来定义对象的结构,包含属性、方法和索引签名等。
    • interface 可以被合并,当多次定义同名的 interface 时,它们会自动合并为一个。
    interface Person {
         
      name: string;
      age: number;
    }
    
    interface Person {
         
      gender: string;
    }
    
    // 合并后等同于:
    // interface Person {
         
    //   name: string;
    //   age: number;
    //   gender: string;
    // }
    
  2. type

    • type 是用来定义任意类型的类型别名。
    • 它可以用来定义原始类型、联合类型、交叉类型、函数类型等。
    • type 不能被合并,当多次定义同名的 type 时,会报错。
    • 要合并需要用 & 连接
    type Age = number;
    
    type Gender = "male" | "female";
    
    type Person = {
         
      name: string;
      age: Age;
      gender: Gender;
    };
     type both = Person & Age // 这样将两个类型合并成一个
    
  3. 使用场景:

    • interface 通常用于描述对象的结构,它更适合用于定义对象和类的类型。
    • type 可以定义更复杂的类型,包括联合类型、交叉类型和函数类型等,它更适合用于定义临时的类型别名。
目录
相关文章
|
1月前
|
JavaScript 前端开发 开发者
TypeScript一
JavaScript开发迅速但维护成本高,适合小型项目,因其动态类型导致编辑器提示不全。TypeScript是JS超集,增加了类型系统,提高开发效率和代码质量。安装TypeScript需先安装Node.js,然后通过npm安装tsc。案例演示创建`.ts`文件,转换成`.js`并运行。TypeScript支持多种数据类型,如any、number、string等,并有严格变量声明和函数定义规则,包括函数重载和匿名函数。
|
1月前
|
存储 JavaScript 索引
TypeScript四
## 联合类型 联合类型使用`|`分隔,表示变量可为多种类型: ```c var val: string | number; val = 12; // OK val = &quot;Runoob&quot;; // OK `
|
1月前
|
JavaScript 前端开发 Java
TypeScript
TypeScript是JavaScript的一个超集,简称ts,ts是能够完全兼容js的ts是一门静态类型的语言,js是动态类型的语言
37 0
|
10月前
|
JavaScript
【TypeScript理解】
【TypeScript理解】
|
JavaScript 前端开发 安全
快速了解 TypeScript
快速了解 TypeScript
|
JSON JavaScript 前端开发
Typescript知识总结(1)
Typescript知识总结(1)
Typescript知识总结(1)
|
JavaScript
初识 TypeScript 一。
初识 TypeScript 一。
初识 TypeScript 一。
|
Rust JavaScript 前端开发
C# 是 TypeScript 的最佳替补?
C# 是 TypeScript 的最佳替补?
223 0
C# 是 TypeScript 的最佳替补?
|
JavaScript 前端开发 编译器
【TypeScript】一文带你了解什么是TypeScript
【TypeScript】一文带你了解什么是TypeScript
【TypeScript】一文带你了解什么是TypeScript
|
JSON JavaScript 前端开发
TypeScript: 为什么必须学
基础动因 对JS执行原理有过了解的同学应该知道,JS代码在执行过程中才会编译,许多文章里引入一个叫做预编译的概念,其实就是我们之前文章说过的执行上下文的创建过程。也就意味着,JS的语法规则检测,是在执行过程中才会进行的一个步骤。 带来的后果就是,在开发过程中的所有语法错误,我们都没办法通过某种方式去完全预知到,而必须在浏览器里执行一次看到报错之后才知道自己某个地方写错了。
164 0
TypeScript: 为什么必须学