TypeScript

TypeScript的优势

TypeScript提供了静态类型检查、面向对象编程能力的增强、更好的工具支持等一系列优势。以下是对TypeScript主要优势的详细分析:

  • 类型安全:TypeScript通过静态类型检查,能够在编译时发现潜在错误,减少运行时错误,从而提高代码的可靠性。
  • 更好的IDE支持:TypeScript的类型信息使得现代编辑器(如VS Code)能够提供更丰富的智能提示和代码补全功能,显著提高开发效率。
  • 代码可维护性:TypeScript鼓励使用接口和类型定义,使得大型项目的代码更易于维护和扩展。
  • 生产力工具的提升:TypeScript与VS Code等工具的集成,提供了代码自动完成、重构工具、静态分析工具等,进一步提升开发效率。
  • 静态代码分析能力:解决原先在运行时(runtime)JavaScript无法发现的错误,通过静态分析提高代码质量。
  • 易于项目后期维护、重构:当版本迭代时,TypeScript的编译器会给予警告或错误提示,帮助开发者保持代码的一致性和稳定性。

TypeScript与JavaScript的对比

  • JavaScript的优势:简单易学,广泛支持,丰富的生态系统。
  • TypeScript的劣势:学习曲线相对陡峭,配置和编译过程更为复杂。

TypeScript通过其静态类型系统和强大的工具支持,为开发者提供了一个更加可靠、高效的开发环境。尤其是在大型项目和团队协作中,TypeScript的优势更加明显。

和 JavaScript 的区别

Typescript 是 JavaScript 的超集,可以被编译成 JavaScript 代码。 用 JavaScript 编写的合法代码,在 TypeScript 中依然有效。Typescript 是纯面向对象的编程语言,包含类和接口的概念。 程序员可以用它来编写面向对象的服务端或客户端程序,并将它们编译成 JavaScript 代码。

TypeScript和 JavaScript的关系

TypeScript 引入了很多面向对象程序设计的特征,包括:

interfaces  接口
classes  类
enumerated types 枚举类型
generics 泛型
modules 模块
主要不同点如下:

TS 是一种面向对象编程语言,而 JS 是一种脚本语言(尽管 JS 是基于对象的)。
TS 支持可选参数, JS 则不支持该特性。
TS 支持静态类型,JS 不支持。
TS 支持接口,JS 不支持接口。

unknown和any区别

在 TypeScript 中,unknownany 都可以用来表示未知类型的值,但它们在类型安全方面有很大的不同。

any

any 是 TypeScript 中的一个特殊类型,它表示任何 JavaScript 值。当你使用 any 类型时,TypeScript 编译器会关闭对该值的类型检查,这意味着你可以对该值执行任何操作,而不会收到编译错误。这可能会导致潜在的运行时错误,因为类型检查被绕过了。

let value: any = "Hello, World!";
value = 42; // 可以赋值为任何类型

unknown

unknown 是 TypeScript 中的一个更安全的未知类型。与 any 不同,当你使用 unknown 类型时,TypeScript 编译器会对该值进行类型检查。你不能对 unknown 类型的值执行任何操作,除非你先对其进行类型断言或类型检查

let value: unknown = "Hello, World!";
// value.toUpperCase(); // 错误:不能对 unknown 类型的值调用方法

if (typeof value === "string") {
  value.toUpperCase(); // 正确:先进行类型检查
}

总结

  • any 类型会关闭类型检查,可能导致潜在的运行时错误。
  • unknown 类型在编译时进行类型检查,更安全,但需要显式地进行类型断言或类型检查。

在实际开发中,推荐使用 unknown 类型,因为它提供了更好的类型安全性。只有在确实需要绕过类型检查的情况下,才使用 any 类型。

type 和 interface

  • 用interface描述数据结构,用type描述类型
  • type 可以声明基本类型别名,联合类型,元组等类型

在 TypeScript 中,typeinterface 都是用来定义对象类型的方式,但它们之间有一些重要的区别:

type

type 关键字可以用来定义一个对象的形状,也可以用来定义联合类型、交叉类型、元组等。

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

type StringOrNumber = string | number;

interface

interface 关键字也用来定义对象的形状,但与 type 不同的是,interface 可以被声明合并(declaration merging),这意味着如果你多次声明同一个接口,它们会被合并成一个接口。

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

// 在另一个地方
interface Person {
  address: string;
}

// 最终的 Person 接口会是这样
interface Person {
  name: string;
  age: number;
  address: string;
}

区别

  1. 声明合并:如上所述,interface 支持声明合并,而 type 不支持。
  2. 联合类型type 可以定义联合类型(如上面的 StringOrNumber),而 interface 不能。
  3. 实现:类可以实现(implements)接口,但不能实现类型别名。
  4. 扩展interface 可以通过 extends 关键字来扩展其他接口,而 type 可以通过交叉类型来达到类似的效果。

使用建议

  • 如果你需要定义一个可以被类实现的接口,或者你需要使用声明合并,那么应该使用 interface
  • 如果你需要定义联合类型、交叉类型,或者你不需要声明合并的功能,那么可以使用 type

总的来说,typeinterface 都是 TypeScript 中定义类型的重要工具,选择使用哪一个取决于你的具体需求。

泛型

  • 泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,使用时再去指定类型的一种特性。可以把泛型理解为代表类型的参数。
interface Test<T = any> {
    userId: T;
}
type TestA = Test<string>;
type TestB = Test<number>;
const a: TestA = {
    userId: '111',
};
const b: TestB = {
    userId: 2222,
};

ts类

Typescript是一种面向对象的Javascript语言,和其他任何面向对象编程的强语言一样,类是描述某一组对象共有属性状态或行为的实体。它就是构建具体对象实例的模板和蓝图。

特性:

1:继承

2:多态

3:抽象

4:封装

5:实例

Pick

从一个已存在的类型中“挑选”出一个或多个属性,创建一个新的类型。这对于类型映射、条件类型以及创建基于现有类型的新类型时非常有用。

Pick类型的基本语法如下:

type Pick<T, K extends keyof T> = {
	[P in K]: TP;
};

T 是原始类型,K 是 T 的属性名的集合(通过 keyof T 获取),Pick 创建一个新的类型,这个新类型只包含 K 中指定的属性。

使用示例
假设我们有如下的TypeScript接口:

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

如果我们只想从一个 Person 类型的对象中选取 name 和 age 属性,我们可以这样做:

type PersonDetails = Pick<Person, 'name' | 'age'>;

// 现在 PersonDetails 类型等价于:
// type PersonDetails = {
//     name: string;
//     age: number;
// }

const personDetails: PersonDetails = {
    name: 'Alice',
    age: 30,
    // 如果尝试添加 location 属性,TypeScript 将报错,因为 PersonDetails 不包含该属性
    // location: 'New York'
};

实际应用
Pick 在处理复杂类型映射时非常有用,特别是在结合其他工具类型(如 Omit、Partial、Required 等)时。例如,你可能有一个复杂的对象,但只需要其部分属性用于某个特定的函数或组件。通过使用 Pick,你可以轻松地创建一个仅包含所需属性的新类型,从而保持类型安全和代码清晰度。

注意事项
Pick 中的 K 必须是 T 的有效键名集合。如果尝试选取 T 中不存在的属性,TypeScript 将报错。
Pick 创建的类型是静态的,即在编译时确定。它不会根据运行时的数据动态改变。
Pick 是TypeScript类型系统中一个非常强大的工具,能够帮助你以类型安全的方式处理复杂的类型映射问题。

在TypeScript中,Omit、Partial、Required 是三个非常有用的内置工具类型,它们允许你以声明式的方式修改现有类型的属性。这些工具类型在类型映射、条件类型以及复杂类型操作中特别有用。

Omit

Omit<T, K>
从一个对象类型中排除某些属性,把剩下的组成新类型。这个新类型包含 T 中除了 K 指定的属性之外的所有属性。

语法:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
(注意:上面的 Omit 定义是基于 Pick 和 Exclude 的,但实际上在TypeScript中是直接提供的。)

示例:

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

type PersonWithoutLocation = Omit<Person, 'location'>;

// 现在 PersonWithoutLocation 类型等价于:
// type PersonWithoutLocation = {
//     name: string;
//     age: number;
// }

Partial

Partial<T>
Partial 工具类型将类型 T 的所有属性变为可选的(即属性后加上 ?)。这意味着你可以省略这些属性,或者为它们提供值。

语法:

type Partial<T> = {
    [P in keyof T]?: T[P];
};

示例:

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

type PartialPerson = Partial<Person>;

// 现在 PartialPerson 类型等价于:
// type PartialPerson = {
//     name?: string;
//     age?: number;
// }

Required

Required<T>
与 Partial 相反,Required 工具类型将类型 T 的所有属性变为必需的(即移除所有属性后的 ?)。这在你想要确保一个对象具有所有必需的属性时非常有用。

语法:

type Required<T> = {
    [P in keyof T]-?: T[P];
};
(注意:-? 语法是TypeScript特有的,用于移除可选性。)

示例:

interface PartialPerson {
    name?: string;
    age?: number;
}

type RequiredPerson = Required<PartialPerson>;

// 现在 RequiredPerson 类型等价于:
// type RequiredPerson = {
//     name: string;
//     age: number;
// }

Readonly

将类型转化为只读

export interface Contact{
  readonly  name: string; // 赋值后姓名不可修改
  phone?: string; // 手机号
  email: string; // 邮箱
  avatar: string; // 头像
  userid: string; // id
}

Readonly源码实现

type Readonly<T> = {
readonly [P in keyof T]: T[P];
};

Exclude

Exclude (排除/不包括),一般用于处理联合类型

Exclude源码
type Exclude<T, U> = T extends U ? never : T;

处理联合类型

type Test1 = '1' | '2' | '3'
const obj: Exclude<Test1, '1' | '2'> = '3'; // 3 OK 赋值1,2就会error

Extract

Extract (提取/包括),和 Exclude 正好相反,也是用于处理联合类型

Extract实现源码
type Extract<T, U> = T extends U ? T : never;
// 处理联合类型

type Test1 = '1' | '2' | '3'

const obj: Extract<Test1, '1' | '2'> = '1'; // 1,2 OK 赋值3就会error

ReturnType

ReturnType (函数的类型推导返回)
ReturnType源码

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

ReturnType案例

// 正确用法
const myFun = () => ({
    name: 'zhangsan',
    age: 233,
    sex: '1',
    tel: 123456789,
    fun: () => {
        return 233;
    },
    arr: [1,2,3,4,5,6]
});


type Test2 = ReturnType<typeof myFun>; // OK 鼠标放到Test2上可以发现 已推导出了myFun函数的返回类型。

// 错误用法
const someValue = 42;  
type InvalidReturnType = ReturnType<typeof someValue>; // error错误!someValue 不是一个函数。

NonNullable

NonNullable (类型中排除 null 和 undefined)
源码

type NonNullable<T> = T & {};

泛型参数T和{}的交集就默认排除了nullundefined

NonNullable的使用案例

type MaybeString = string | null | undefined;  

const value: MaybeString = getSomeStringValue(); // 假设这个函数可能返回一个字符串、null 或 undefined  

// 使用 NonNullable 确保 value 不会是 null 或 undefined  
const nonNullableValue: NonNullable<MaybeString> = value!; // 使用 ! 断言操作符,或者通过其他方式确保值不为 null 或 undefined  

// 现在,nonNullableValue 的类型是 string,因为我们已经排除了 null 和 undefined  
console.log(nonNullableValue.length); // 这是安全的,因为我们知道 nonNullableValue 一定是字符串

// 其实就是某些场景绝对为了排除null,undefined的类型才用的

在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 ! 可以用于断言操作对象是非 null 和非 undefined类型。具体而言,x! 将从 x 值域中排除 null 和 undefined 。

注意事项
这些工具类型都是在编译时解析的,不会影响运行时的JavaScript代码。
它们都是TypeScript语言的一部分,因此你不需要安装任何额外的库来使用它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值