TypeScript入门详解

TypeScript初识

TS是带类型语法的JS

官方网站:www.typescriptlang.org/

TypeScript 是一种带有 类型语法 的 JavaScript 语言,在任何使用 JavaScript 的开发场景中都可以使用。 JavaScript 代码

js 复制代码
// 没有明确的类型 
let age = 18

TypeScript 代码

ts 复制代码
// 有明确的类型,可以指定age是number类型(数值类型) 
// let 变量名 : 数据类型 = 值
let age: number = 18

注意:TS 需要编译才能在浏览器运行。

总结:TS 是 JS 的超集,支持了JS 语法和扩展了类型语法。

TypeScript 作用

TS作用是在编译时进行类型检查提示错误

  • JS是动态类型的编程语言,动态类型最大的特点就是它只能在 代码执行 期间做类型的相关检查,所以往往你发现问题的时候,已经晚了。
  • TS 是静态类型的编程语言,代码会先进行编译然后去执行,在 代码编译 期间做类型的相关检查,如果有问题编译是不通过的,也就暴露出了问题。
  • 配合 VSCode 等开发工具,TS 可以提前到在 编写代码 的时候就能发现问题,更准确更快的处理错误。

TS 优势

  • 更早发现错误,提高开发效率
  • 随时随地提示,增强开发体验
  • 强大类型系统,代码可维护性更好,重构代码更容易
  • 类型推断机制,减少不必要类型注解,让编码更简单

☆ Vue3源码TS重写,React和TS完美配合,Angular默认支持TS,大中型前端项目首选。

TypeScript 核心

类型注解

示例代码 :

类型注解 复制代码
// 约定变量 age 的类型为 number 类型 
let age : number = 18; 
age = 19;
  • : number 就是类型注解,它为变量提供类型约束。
  • 约定了什么类型,就只能给该变量赋值什么类型的值,否则会报错。
  • 而且:约定类型之后,代码的提示也会非常清晰。

错误演示 :

错误演示 复制代码
let age: number = 18; 
// 报错:不能将类型"string"分配给类型"number" 
age = '19';

总结 :

  • 什么是类型注解?

    • 变量后面约定类型的语法,就是类型注解
  • 类型注解作用?

    • 类型约束,明确提示

TS常用类型

  • JS 已有类型

    • 简单类型,number string boolean null undefined
    • 复杂类型,对象 数组 函数
  • TS 新增类型

    • 联合类型、自定义类型(类型别名)、接口、元组、字面量类型、枚举、void、any、泛型 等

原始类型

语法 : :数据类型

  • js基本数据类型 : string / number / boolean / null / undefined
  • null 和 undefined使用较少 , 一般作为初始值
原始类型 复制代码
/**
 * 原始类型
 */
 {
  // 1.数字类型
  let number : number = 1
  // 2.字符串类型
  let string : string = '2'
  // 3.布尔类型
  let boolean : boolean = true
  // 4.null
  let nullValue : null = null
  // 5.undefined
  let undefinedValue = undefined
}

数组类型

数组类型注解分为两种

  • 写法一 : 类型[]
类型 复制代码
 {
  //语法 :`类型[]`
  // 数字数组
  let numArr : number[] = [1,2,3]
  // 字符串数组
  let strArr : string[] = ['1','2','3']
}
  • 写法二 : Array<类型>
Array<类型> 复制代码
>  //语法 :`Array<类型>` 
  // 布尔类型数组
  let booleanArr : Array<boolean> = [true , false]
}

推荐使用: 类型[] 写法

联合类型

类型与类型之间使用 | 连接,代表类型可以是它们当中的其中一种,这种类型叫:联合类型 ( 联合类型可以将多个类型合并为一个类型 )

☆ 示例 :数组中有 numberstring 类型,这个数组的类型如何书写?

联合类型 复制代码
let arr: (number | string)[] = [1, 'a', 3, 'b'];

☆ 案例 :给一个定时器 ID 加类型

  • 初始化timer ,timer类型为null
  • 给timer赋值定时器 , 此时timer类型为number类型
联合类型 复制代码
// timer 的类型注解是数字类型或null类型
let timer: number | null = null; 
timer = setInterval(() => {}, 1000);

类型别名

基本语法 : type 类型别名 = 具体类型 基本语法

  • 定义类型别名,遵循大驼峰命名规范,类似于变量
  • 使用类型别名,与类型注解的写法一样即可

示例代码 :

类型别名 复制代码
// let arr: ( number | string )[] = [ 1, 'a', 4] 
// 类型别名: type 类型别名 = 具体类型 
type CustomArr = (number | string)[]; 
let arr: CustomArr = [1, 'a', 4];

总结 : 当同一类型(写法复杂)被多次使用时,可以通过类型别名,简化 该类型的使用 , 提高代码的复用性 ,方便后期维护

函数类型

给函数指定类型,其实是给 参数返回值 指定类型

两种写法:

  1. 在函数基础上 分别指定 参数和返回值类型
  2. 使用类型别名 同时指定 参数和返回值类型

示例代码 :分别指定

分别指定 复制代码
// 函数声明 
function add(num1: number, num2: number): number { return num1 + num2; } 
// 箭头函数 
const add = (num1: number, num2: number): number => { return num1 + num2; };

示例代码 :同时指定

分别指定 复制代码
type AddFn = (num1: number, num2: number) => number;
const add: AddFn = (num1, num2) => { 
        return num1 + num2; 
   };

☆注意:

通过类似箭头函数形式的语法来为函数添加类型,只适用于 函数表达式

void 类型

void 是函数返回值类型

  • 如果函数没有返回值,定义函数类型时返回值类型为 void
void 复制代码
const say = (): void => { 
        console.log('hi'); 
      };
  • 如果函数没有返回值,且没有定义函数返回值类型的时候,默认是 void
void 复制代码
const say = () => { 
        console.log('hi'); 
      };

可选参数

如果函数的参数,可以传也可以不传,这种情况就可以使用 可选参数

☆ 语法 : 参数后加 ? 即可

可选参数 复制代码
const fn = (n?: number) => { // .. };
fn();  // 可以不传参
fn(10);

注意: 必选参数不能位于可选参数后

对象类型

TS 的对象类型,其实就是描述对象中的 属性 方法 的类型,因为对象是由属性和方法组成的。

空对象 :

空对象 复制代码
 let person: {} = {};

有属性的对象 :

有属性的对象 复制代码
let person: { name: string } = { 
                name: '同学'
            };

有属性和方法的对象

有属性和方法的对象 复制代码
let person: { 
            name: string; 
            sayHi(): void; 
           } = { 
                name: 'jack', 
                sayHi() {}, 
            };

小结 :

  • 使用声明描述对象结构?{}
  • 属性怎么写类型?属性名: 类型
  • 方法怎么写类型? 方法名(): 返回值类型

对象类型-扩展用法:

  • 函数使用箭头函数类型
箭头函数 复制代码
let person: { name: string sayHi: () => void } = { 
                                              name: 'jack',
                                              sayHi() {}, 
                                             };
  • 对象属性可选
对象属性可选 复制代码
// 例如:axios({url,method}) 如果是 get 请求 method 可以省略
 const axios = (config: { url: string; method?: string }) => {};
  • 使用类型别名
使用类型别名 复制代码
// {} 会降低代码可阅读性,建议对象使用类型别名 
// const axios = (config: { url: string; method?: string }) => {}; 
type Config = { url: string; method?: string; }; 
const axios = (config: Config) => {};

小结:

  • 对象的方法使用箭头函数类型写法 : {sayHi:()=>void}
  • 对象的可选参数设置 : {name?: string}
  • 对象类型会使用 {} 如何提供可阅读性? 类型别名

接口 interface

接口声明是命名对象类型的另一种方式

接口interface 复制代码
// 通过interface定义对象类型 
interface Person { 
     name: string; 
     age: number; 
     sayHi: () => void; 
   } 
// 使用类型 
let person: Person = { 
    name: 'jack', 
    age: 19, 
    sayHi() {}, 
   };

小结:

  • interface 后面是接口名称,和类型别名的意思一样。
  • 指定 接口名称 作为变量的类型使用。
  • 接口的每一行只能有 一个 属性或方法,每一行不需要加分号。

interface 继承

语法 : 接口A extends 接口B

使用场景 :有两个接口,有相同的属性或者函数,如何提高代码复用?

使用场景 复制代码
// 两个接口有相同的x,y属性
interface Point2D { 
        x: number; 
        y: number; 
      } 
interface Point3D { 
        x: number; 
        y: number; 
        z: number; 
      }

可以将相同的属性或展示可以抽离出来,然后使用 extends 实现继承复用:

extends 复制代码
interface Point2D { 
          x: number;
          y: number; 
        } 
// 继承 Point2D 
interface Point3D extends Point2D { 
          z: number; 
        } 
// 继承后 Point3D 的结构:{ x: number; y: number; z: number }

小结:

  • 接口继承的语法:interface 接口A extends 接口B {}
  • 继承后 接口A 拥有 接口B 的所有属性和函数的类型声明

type 交叉类型

语法 : type1 & type2

使用场景 : 实现 Point2D{z: number} 类型合并得到 Ponit3D 类型

type交叉类型 复制代码
// 使用 type 来定义 Point2D 和 Point3D 
type Point2D = { 
          x: number; 
          y: number; 
        };
// 使用 交叉类型 来实现接口继承的功能: 
// 使用 交叉类型 后,Point3D === { x: number; y: number; z: number } 
type Point3D = Point2D & { 
           z: number; 
         };
let obj: Point3D = { 
           x: 1, 
           y: 2, 
           z: 3, 
         };

小结:

  • 使用 & 可以合并连接的对象类型,也叫:交叉类型

interface & type

  • 类型别名和接口非常相似,在许多情况下,可以在它们之间自由选择
  • 接口的几乎所有特性都以类型的形式可用,关键的区别在于不能重新打开类型以添加新属性,而接口总是可扩展的。

interface和type的相同点 :

  • 都可以声明对象类型

  • 都可以复用
    interface和type的不同点 :

  • type可以声明其他类型 , interface不可以

  • type复用语法 : &交叉类型 ; interface复用语法 :extends

  • type不可以重复声明 , 会报错 ; interface可以重复声明 , 属性和方法会合并

类型推断

在 TS 中存在类型推断机制,在没有指定类型的情况下,TS 也会给变量提供类型。
  • 声明变量并初始化时
声明变量并初始化时 复制代码
// 变量 age 的类型被自动推断为:
number let age = 18;
  • 决定函数返回值时
决定函数返回值时 复制代码
// 函数返回值的类型被自动推断为:number
 const add = (num1: number, num2: number) => { 
              return num1 + num2; 
            };

建议:

  • 将来在开发项目的时候,能省略类型注解的地方就省略,充分利用TS推断 的能力,提高开发效率。
  • 在你还没有熟悉 ts 类型的时候建议都加上类型,比如今天第一次写 ts 最好都写上
  • 如果你不知道类型怎么写,可以把鼠标放至变量上,可以通过 Vscode 提示看到类型

字面量类型

使用 js字面量 作为变量类型,这种类型就是字面量类型

字面量类型 复制代码
// : 'jack' 是字面量类型 
let name: 'jack' = 'jack'; 
// : 18 是字面量类型 
let age: 18 = 18; 

// 报错:不能将类型"19"分配给类型"18"
age = 19;

字面量类型应用 : 性别只能是男和女 ,不会出现其他值

应用 复制代码
type Gender = '男' | '女' 
let gender: Gender = '男' 
gender = '女'

小结:

  • 字面量类型配合联合类型来使用,表示:一组明确的可选的值

类型断言

有时候自己会比 TS 更加明确一个值的类型,此时,可以使用类型断言来指定更具体的类型 , 例如 : a标签

类型断言 复制代码
// aLink 的类型 HTMLElement,该类型只包含所有标签公共的属性或方法 
// 这个类型太宽泛,没包含 a 标签特有的属性或方法,如 href 
const aLink = document.getElement(#link)
  • 我们明确知道获取的是一个 a 标签,可以通过 类型断言 给它指定一个更具体的类型
类型断言 复制代码
const aLink = document.getElementById('link') as HTMLAnchorElement

小结:

  1. 使用 as 关键字实现类型断言
  2. 关键字 as 后面的类型是一个更加具体的类型(HTMLAnchorElement 是 HTMLElement 的子类型)
  3. 通过类型断言,aLink 的类型变得更加具体,这样就可以访问 a 标签特有的属性或方法了

三种方法可以获取具体类型进行类型断言:

  • console.dir() 打印标签
  • document.createElement('a') 创建元素
  • document.queryselector('img') 获取元素
相关推荐
YUELEI1182 小时前
TypeScript 封装 Axios 1.7.7
typescript·axios
bobostudio19957 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
Tiffany_Ho15 小时前
【TypeScript】知识点梳理(三)
前端·typescript
看到请催我学习19 小时前
如何实现两个标签页之间的通信
javascript·css·typescript·node.js·html5
天涯学馆1 天前
Deno与Secure TypeScript:安全的后端开发
前端·typescript·deno
applebomb1 天前
【2024】uniapp 接入声网音频RTC【H5+Android】Unibest模板下Vue3+Typescript
typescript·uniapp·rtc·声网·unibest·agora
读心悦2 天前
TS 中类型的继承
typescript
读心悦2 天前
在 TS 的 class 中,如何防止外部实例化
typescript
Small-K2 天前
前端框架中@路径别名原理和配置
前端·webpack·typescript·前端框架·vite
宏辉2 天前
【TypeScript】异步编程
前端·javascript·typescript