重新整理TypeScript基础语法

一、TypeScript 简介

TS 时 JS 的超集,由 Ts 编写的程序会转化为 Js,因此 Ts 程序可以在任何支持 Js 语言的环境上运行。

使用 Ts 优势:

  • 强大的类型系统;
  • 更高的可维护性;
  • 生态系统与工具支持;
  • 渐进式应用;
  • 庞大的社区与学习资源;

二、安装与配置

安装前请确保已经安装了 node 环境;

npm install typescript  //使用npm安装  全局安装添加 -g
pnpm add typescript  //使用pnpm安装 全局安装添加 -g
yarn add typescript //使用yarn安装 全局安装添加 -g

// 初始化ts,在终端输入tsc --init生成默认的ts.config.json

三、ts 基本语法

变量声明与类型注解

// 变量声明与类型注解
// js
let num = 1;
// ts
let num1: number = 1;
const boo: boolean = true;
let str = <string>"hello world";

函数与箭头函数

// 函数与箭头函数
// js——函数
function countNumJS(num1, num2) {
  return num1 + num2;
}
// ts-函数 可以在参数位置添加类型声明,参数后添加出参类型声明
function countNumTS(num1: number, num2: number): number {
  return num1 + num2;
}
// js——箭头函数
const arrowFunctionJS = (a, b) => a + b;
// ts——箭头函数
const arrowFunctionTS = (a: number, b: number): number => a + b;
console.log(arrowFunctionJS(1, "2"));
console.log(countNumTS(1, 2));
console.log(countNumTS("1", 2)); //报错,string类型不能赋给number类型
console.log(arrowFunctionJS(1, 2));
console.log(arrowFunctionTS(1, 2));
console.log(arrowFunctionTS(true, 2)); //报错,boolean类型不能赋给number类型

类与接口

type Point = {
  x: number;
  y: number;
  title: string;
};
// 使用类型——普通使用
let point1: Point = { x: 1, y: 1, title: "point" };
let pointErr: Point = { x: "1", y: "1", title: 12 }; //报错,与类型中声明的数据类型不一致
// 使用类型——注解使用
let Point2 = <Point>{
  x: 1,
  y: 1,
  title: "point",
};

接口

// 可以使用interface关键字定义一个接口
interface Person {
  name: string;
  age: number;
  tel: string;
}
// 使用接口——普通使用
let person1: Person = {
  name: "Tom",
  age: 18,
  tel: "15511554114",
};
// 使用接口——注解使用
let person2 = <Person>{
  name: "Tom",
  age: 18,
  tel: "15511554114",
};
let personErr = <Person>{
  name: 151,
  age: "18",
  tel: 784144114,
}; //报错,与类型中声明的数据类型不一致

class 实现接口

// 使用class来实现接口
class Student implements Person {
  constructor(public name: string, public age: number, public tel: string) {}
}
const student1 = new Student("tom", 18, "15544141114");
console.log(student1);

接口继承

// 接口继承
interface Worker extends Person {
  getAddress(): void;
}
// 实现Worker
// NetWorker继承了Worker
class NetWorker implements Worker {
  constructor(public name: string, public age: number, public tel: string) {}
  getAddress(): void {
    console.log("我的家在东北");
  }
}

const netWorker = new NetWorker("tom", 18, "15544141114");
netWorker.getAddress(); //输出‘我的家在东北’

使用 interface 关键字定义函数

// 使用interface关键字定义函数
interface getInfo {
  (personName: string, age: number): void;
}

const returnInfo: getInfo = (personName, age) => {
  console.log(`我叫${personName},我今年${age}岁了`);
};
returnInfo("Tom", 18);
returnInfo(true, "12"); //报错

// 接口定义可选值,和只读属性
interface Tom {
  name: string;
  age?: number; //age属性可选
  readonly address: string; // address属性只可以读取不能修改
}

类型与接口的区别

在 TypeScript 中,类型(Type)和接口(Interface)都用于定义数据结构的形状,但它们有一些不同之处。以下是类型和接口之间的主要区别:

  1. 基本区别:

类型(Type):类型别名(Type Alias)可以为现有类型起一个新的名字,可以是基本类型、联合类型、交叉类型等。

接口(Interface):接口用于定义一个对象的结构,可以包含属性、方法等。 2. 可重用性:

类型(Type):类型别名可以在多个地方重复使用。

接口(Interface):接口可以被继承和实现,从而可以在多个类或对象上共享结构。 3. 合并(Merging):

类型(Type):无法合并同名的类型别名。

接口(Interface):可以合并同名的接口定义,这意味着如果你定义了多个同名接口,它们会自动合并成一个。 4. 实现:

类型(Type):不能用于实现类或对象。

接口(Interface):可以被类实现,用于强制类遵循特定的结构。 5. 扩展(Extending):

类型(Type):不能扩展或继承。

接口(Interface):可以通过继承扩展其他接口。 6. 可选属性和只读属性:

类型(Type):无法定义可选属性和只读属性。

接口(Interface):可以定义可选属性和只读属性。 7. 类型推断和表达式:

类型(Type):可以使用泛型进行复杂的类型操作和计算。

接口(Interface):不能执行复杂的类型操作。

总的来说,类型和接口在某些情况下可以互换使用,但在特定情境下可能更适合使用其中之一。例如,如果您要描述一个类或对象的结构,并且需要实现继承、合并等特性,那么接口是更好的选择。而如果您需要对现有类型起一个别名,或者执行复杂的类型操作,那么类型别名可能更合适。

命名空间与模块

命名空间

在 Ts 中,支持使用 namespace 关键字开辟一块命名空间

// 定义一个命名空间
namespace Space {
  export const name: string = "Tom"; // 要想在外部使用命名空间中的变量,就必须使用export关键字暴露出去,否则五大获取
  const age: number = 18;
}
console.log(Space.name);
console.log(Space.age); // 类型“typeof Space”上不存在属性“age”

使用场景:

  • 避免全局命名冲突:当你的应用中引入多个第三方库或模块时,可以将它们包裹在不同的命名空间中,以防止命名冲突。
  • 组织相关代码:当你有一些相关的函数、类、接口等,你可以将它们放在同一个命名空间内,以便更好地组织代码结构。

模块

在 Ts 中,支持使用 module 关键字来定义一个模块

// 模块
module Module {
  const name: string = "Tom";
  export const sayName = () => {
    console.log(name);
  };
}
Module.sayName();
Module.name; // 类型“typeof Module”上不存在属性“name”

使用场景

  • 构建大型应用:当你在构建大型的应用程序时,模块可以帮助你将代码分割成更小的、可管理的部分,使代码更具可维护性。
  • 代码复用:你可以将通用的功能封装在一个模块中,并在多个地方重复使用,从而避免重复编写相同的代码。
  • 加载优化:在浏览器环境中,模块系统可以帮助实现按需加载,提升应用的加载性能。

数组与元组

数组(Array):

数组是一种有序的数据结构,用于存储一组相同类型的值。在 TypeScript 中,数组的类型可以使用以下两种方式进行声明:

类型后缀声明:type[] 表示一个该类型的数组。例如,number[] 表示一个由数字组成的数组。

泛型声明:使用泛型数组类型,比如 Array,表示一个由数字组成的数组。

示例:

const numbers: number[] = [1, 2, 3, 4];
const names: string[] = ["Alice", "Bob", "Charlie"];

数组的特点:

元素可以是相同类型的。

可以动态添加、删除元素。

数组长度可以在运行时改变。

可以使用数组方法(如 push、pop、shift、unshift 等)进行操作。

元组(Tuple):

元组是一种特殊的数组,它允许在声明时指定每个元素的类型,并且元素的数量是固定的。元组允许在一个数组中存储不同类型的值,但这些值的类型和顺序是事先确定的。在 TypeScript 中,元组的类型可以通过以下方式声明:

// 元组
// 写过React函数式组件的比较熟悉这里的写法例如 const [state,setState] = useState()
const [username, age] = <[string, number]>["Tom", 12];
console.log(username, age);

元组的特点:

元素的数量是固定的,在声明时指定。

每个元素可以有不同的类型。

可以使用索引访问元素。

元素类型的约束在编译时得到保证。

需要注意的是,元组虽然具有灵活性,但过度使用可能会降低代码的可读性和维护性。在使用元组时,建议仔细考虑元素的顺序和类型,以确保代码的可靠性。

总结:数组用于存储一组相同类型的值,而元组用于存储固定数量、不同类型的值。选择数组还是元组取决于你的需求,以及对类型安全性和代码结构的考虑。

枚举与联合类型

Ts 中使用 enum 关键字来定义一个枚举值,它的本质是一个对象。

TypeScript 枚举可以在以下几个方面进行解释:

  • 编译时静态类型:TypeScript 枚举在编译时被转化为一个对象,其中包含了枚举成员及其与对应值之间的映射关系。这个对象的类型会在编译时检查,从而确保只能使用枚举中定义的成员。
  • 反向映射:TypeScript 枚举提供了一种从值到枚举成员的反向映射。这意味着你可以通过枚举的值获取到对应的枚举成员。反向映射在某些情况下能够提供方便的功能,但也可能在一些特定场景下引发问题。
  • 编译结果:TypeScript 编译器会将枚举转化为对应的 JavaScript 代码。对于常数枚举,实际的值会直接嵌入到编译后的代码中,而非常数枚举(含有计算值的成员)则会生成一个运行时对象以保留枚举的结构。
  • 目标环境的影响:枚举的编译结果会受到目标 JavaScript 环境和 TypeScript 编译选项的影响。在一些情况下,枚举可能会被完全移除,而只保留其使用的值。

any never unknown

在 TypeScript 中,any、never 和 unknown 是三种特殊的类型,用于处理不同的情况和类型不确定性。

any:

any 类型是 TypeScript 中的最不严格的类型。它表示任何类型的值都可以被赋给 any 类型,即 TypeScript 编译器不会对其进行类型检查。使用 any 类型可能会降低代码的类型安全性,因为 TypeScript 将不会强制执行类型检查。

let value: any = 42;
value = "Hello";
value = [1, 2, 3];
// 编译器不会报错,因为 value 的类型是 any

never:

never 类型表示那些永远不会出现的值的类型。它通常用于表示抛出异常、无限循环或其他永远不会返回的函数的返回类型。在类型推导中,当 TypeScript 认为某个值会导致程序终止,就会将其类型判定为 never。

function throwError(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) {
    // 无限循环,永远不会返回
  }
}

unknown:

unknown 类型是 TypeScript 2.0 引入的一种类型,用于表示不确定的值。与 any 不同,unknown 类型要求进行类型检查,只有在进行类型检查后,才能将其赋给其他类型。使用 unknown 类型可以在不牺牲类型安全性的情况下处理不确定的值。

let value: unknown = 42;
if (typeof value === "number") {
  let numberValue: number = value; // 类型检查通过
}

function processValue(input: unknown): void {
  if (typeof input === "string") {
    console.log(input.toUpperCase());
  }
}

总结:

  • any 类型是最不受限制的类型,适用于类型不确定的情况,但可能导致类型安全性降低。
  • never 类型表示永远不会出现的值,通常用于表示异常或无限循环。
  • unknown 类型是类型安全的类型,要求在使用前进行类型检查,用于处理不确定的值而不牺牲类型检查。unknown类型可以将自己赋值给其他类型,但是不能把其他类型赋值给unknown

四、高级特性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值