TypeScript入门到精通

学习ts之前,我们首先了解一下我们为什么要学ts,ts是什么?ts比js有不同呢?

TypeScript 是 JavaScript 的一个超集,是由微软开发的自由和开源的编程语言,支持 ECMAScript 6 标准(ES6 教程)。在 JavaScript 的基础上增加了静态类型检查的超集。TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

学习ts的好处:提高代码质量、可维护性和开发效率。 它适用于中大型项目、团队协作、长期维护的系统。

1.类型注解:

类型注解时给变量添加类型约束,使变量只能被赋值为约定好的类型,同时可以有相关的类型提示,:string就是类型注解,说明该变量只能被赋值为string类型

变量:

如果声明变量没有设置类型和初始值,类型可以是任意类型,默认初始值为 undefined

  • string表示文本数据 let name: string = "Alice";
  • number表示数字,包括整数和浮点数 let age: number = 30;
  • boolean表示布尔值 true 或 false let isDone: boolean = true;
  • array表示相同类型的元素数组 let list: number\[\] = 1, 2, 3;
  • tuple表示已知类型和长度的数组 let person: string, number = "Alice", 30;
  • enum定义一组命名常量 enum Color { Red, Green, Blue };
  • any任意类型,不进行类型检查 let value: any = 42;
  • void无返回值(常用于函数) function log(): void {}
  • null表示空值 let empty: null = null;
  • undefined表示未定义 let undef: undefined = undefined;
  • object表示非原始类型 let obj: object = { name: "Alice" };
  • unknown不确定类型,需类型检查后再使用 let value: unknown = "Hello";
数组:

数组被注解为数字类型之后,有两个好处

不仅可以限制变量类型为数组而且可以限制数组成员的类型

不同的类型对应的提示数组的属性和方法也是可以不同的

TypeScript 复制代码
// 类型[]
let arr:number[] = [1]
console.log(arr);

// 数组泛型
let arr1:Array<number> =[2]
console.log(arr1);
联合类型:

可以将多个类型合并为一个类型进行注解

TypeScript 复制代码
let a1:(string|number)[] = ['1',3]
console.log(a1);

let a2:string|number[] = [1] //表示可以存放string或者number类型的数组
console.log(a2);
类型别名type:

通过type关键字可以给写起来比较复杂的类型起一个其他的名字,用来简化和复用类型

TypeScript 复制代码
type ItemType = (string|number)[]
let a3:ItemType = [1,2]
let a4:ItemType = ['1','2']
console.log(a3);
console.log(a4);

2.函数:

函数类型就是函数添加类型注解,本质上就是给函数的参数和返回值添加类型约束

  • 函数参数注解类型之后不但限制了参数的类型还限制了参数为必填
  • 函数类型注解类型之后限制了该函数内部return出去的值必须满足类型需求
TypeScript 复制代码
function add(a:number,b:number){
  return a+b
}
add(1,2)
返回值:

无返回值void

js中有些函数只有功能没有返回值,此时使用void进行返回值注解,明确表示函数没有返回值

注意事项:在js中如何没有返回值,默认返回的是undefined,在ts中void和undefined不是一回事,undefined在ts中是一种明确的简单类型,如果指定返回值是undefined,那么返回值必须是undefined

TypeScript 复制代码
console.log("Task done");
  // 无 return
}
//函数显式返回 undefined
function doTask2(): void {
  return undefined;
}
//undefined 类型显式返回
function doTask4(): undefined {
  console.log("Task done");
  return undefined;
}
函数表达式(箭头函数):

函数表达式的类型注解有两种方式,参数和返回值分开注解和函数整体注解

  1. 参数和返回值分开注解
TypeScript 复制代码
const add1 = (a:number,b:number):number=>{
return a+b
}
add1(1,43)
  1. 函数整体注解(只针对于函数表达式)
TypeScript 复制代码
const add2:Add = (a,b)=>{
  return a+b
}
add2(1,2)

3.interface接口:

接口的可选设置 概念:通过? 对属性进行可选标注,赋值的时候该属性可以缺失,如果有值必须保证类型满足要求

TypeScript 复制代码
interface Props{
  type:string
  size?:string
}

let props:Props = {
  type:'button'
}

props = {
  type:'success',
  size:'large'
}
继承:

接口的很多属性是可以进行类型复用的,使用extends实现接口继承,实现类型复用

TypeScript 复制代码
// 定义一个接口,表示一本书的基本信息
interface Book {
  title: string; // 书名
  price: number; // 价格
}

// 定义一个接口,表示打折后的书籍信息,它继承了 Book 接口
interface DiscountedBook extends Book {
  discountPrice: number; // 打折后的价格
}

// 创建一个符合 DiscountedBook 接口的对象
let myBook: DiscountedBook = {
  title: "TypeScript 基础教程",
  price: 100,
  discountPrice: 80
};

4.字面量类型:

使用js字面量作为类型对变量进行类型注解,这种类型就是字面量类型,字面量类型比普通的类型更加精确

const 是字面量类型而不是string类型!!!

字面量类型在实际应用中通常和联合类型结合起来使用,提供一个精确的可选范围

TypeScript 复制代码
// 字面量类型
type Gender = '男'|'女'
let gender:Gender = '男'

5.type注解对象:

在ts中对于对象类型注解,除了使用interface之外还可以使用类型别名来进行注解,作用相似

TypeScript 复制代码
let gender:Gender = '男'
type Person = {
  name:string,
  age:number
}

let person:Person={
  name:'张三',
  age:18
}
type+交叉类型模拟继承:
TypeScript 复制代码
// type+交叉类型模拟继承
type GoodType = {
  id:string,
  price:number
}

type DisGoodType = GoodType & {
  disPrice:number
}

let car:DisGoodType = {
  id:'1',
  price:100,
  disPrice:80
}

6.类型推论和any类型:

类型断言:

在ts当中,存在类型推断机制,在没有给变量添加类型注解的情况下,ts也会给变量提供类型

TypeScript 复制代码
function ADD(a:number,b:number){
  return a+b
}
const n = ADD(1,2) //会自动推断为number类型
any类型:

变量被注解为any类型之后,ts会忽略类型检查,错误的类型赋值不会报错,也不会有任何提示

TypeScript 复制代码
let obj:any = {
  name:'张三'
}
obj.age = 13
obj()
const a:number = obj //不会报错any类型可以赋值给任何类型

7.类型断言:

有些时候开发者比ts本身更清楚当前的类型是什么,可以使用断言(as) 让类型更加精确和具体

同个as进行类型断言获得更加精确的类型

类型断言的注意事项:

类型断言只能够欺骗typescript编译器,无法避免运行时的错误,滥用断言类型可能会导致运行时错误

TypeScript 复制代码
function log(foo:string|number){
  console.log((foo as number).toFixed(2))
}
log(100)
log('100')//报错

虽然在编译器上没有报错,但是运行的时候会报错

8.泛型:

interface:

泛型是指在定义接口,函数等类型的时候,不预先指定具体类型,而是在使用的时候再指定类型的一种特性,使用泛型可以复用并且让类型更加灵活

在接口类型的名称后面使用即可声明一个泛型参数,接口里的其他成员都能使用该参数类型

TypeScript 复制代码
interface ResDate<T>{}

通用思路:

  1. 找到可变类型的部分,通过泛型抽象为泛型参数(定义参数)

  2. 在使用泛型的时候,把具体类型传入到泛型参数的位置(传参)

TypeScript 复制代码
// 定义通用响应接口(泛型)
interface ApiResponse<T> {
  statusCode: number;
  message: string;
  payload: T;  // 更符合业务场景的命名
}

// 定义具体业务数据类型
interface UserProfile {
  userName: string;
  userAge: number;
}

interface ProductDetails {
  productId: number;
  productName: string;
}

// 用户数据响应示例
const userResponse: ApiResponse<UserProfile> = {
  statusCode: 200,
  message: "操作成功",
  payload: {
    userName: "张三",
    userAge: 18
  }
};

// 商品数据响应示例
const productResponse: ApiResponse<ProductDetails> = {
  statusCode: 200,
  message: "数据获取成功",
  payload: {
    productId: 1,
    productName: "高端智能手机"
  }
};
type:

泛型别名:

在类型别名type的后面使用即可声明一个泛型参数,接口里的其他成员都能使用该参数的类型

TypeScript 复制代码
type ResData<T> = {}
TypeScript 复制代码
// 定义通用的 API 响应类型(泛型)
type ApiResponse<T> = {
  statusCode: number;  // 符合 HTTP 状态码命名规范
  message: string;     // 国际通用的消息字段命名
  payload: T;          // 专业术语表示有效数据负载
}

// 用户数据实体类型
interface UserProfile {
  userName: string;    // 明确用户名称属性
  userAge: number;     // 明确用户年龄属性
}

// 商品数据实体类型
interface ProductInfo {
  productId: number;   // 符合电商领域术语
  productName: string; // 统一使用 product 前缀
}

// 用户数据响应示例
const userDataResponse: ApiResponse<UserProfile> = {
  statusCode: 200,
  message: "用户数据获取成功",
  payload: {
    userName: "张三",
    userAge: 18
  }
};

// 商品数据响应示例
const productDataResponse: ApiResponse<ProductInfo> = {
  statusCode: 200,
  message: "商品信息查询成功",
  payload: {
    productId: 1,
    productName: "智能家居套装"
  }
};
泛型函数:

在函数名称的后面使用 即可声明一个泛型参数,整个函数中(参数,返回值,函数体)的变量都可以使用该参数的类型

TypeScript 复制代码
function fn<T> () {}

需求,设置一个函数createArray,它可以创建一个指定长度的数组,同时将每一项都填充一个默认值(多种类型)

TypeScript 复制代码
// 泛型函数
function createArray<T>(length:number,value:T){
  let res = []
  for(let i = 0; i<length;i++){
    res[i] = value
  }
  return res
}
createArray<number>(2,1)
createArray<string>(2,'hello')
泛型约束:

泛型的特点就是灵活不确定,有些时候泛型函数的内部需要访问一些特定类型数据才有的属性,此时会有类型错误,需要通过泛型约束解决

TypeScript 复制代码
interface lengthObj{
  length:number
}
// 如果不继承就会报错
function logLen<T extends lengthObj>(obj:T){
  console.log(obj.length)
}
 
// logLen(false) //报错--类型boolean不满足lengthObj类型
logLen(['1','2'])
logLen({length:10})
相关推荐
weixin_3823952314 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__14 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.15 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~16 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华17 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子19 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅19 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni20 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学21 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端