TypeScript 学习笔记(一)--- 数据类型和函数相关

一、简介

​ TypeScript 简称 TS,是 JavaScript 的超集,也就是在 JavaScript 的基础上,进行扩展,加入了类型注解等新概念。TS与JS之间的关系,类似于Less/Sass 和 CSS之间的关系,我们在文件中写好的TS代码,最终还是会被编译成JS,然后再去执行。JS是弱类型的语言,而TS是强类型的语言。

​ TS支持各类最新的JS特性,还提供了一套代码的静态检查机制,让问题在编译时就被发现。而重要的是:TS支持像C、Java 等后端语言的某些特性,如枚举、泛型、类型转换、类、接口等。总之,TS的出现,让前端的开发语言变的更完善了。

​ 安装TS: npm i -g typescript

二、类型注解

​ TS 规定在声明变量时,需要明确变量的数据类型,例如:

let age: number = 18  // 限制age只能存储number类型的数据
let name: string = 'Tom'  // 限制name只能存储string类型的数据
...

​ 这种以 变量: 数据类型 的形式,来为变量添加类型约束的方式就是TS的类型注解,你在声明时约定了什么类型,就只能给变量赋什么类型的值,不可发生改变:

let age: number = 18  // 限制age只能存储number类型的数据
age = '二十'  // 如果赋其他类型的值  则会报错

​ 如果一个函数有形参和返回值,那么TS要求在声明函数的时候需要将形参和返回值也进行类型注解:

// 函数名(形参1:数据类型,形参2:数据类型): 返回值的数据类型
// x-数值型 y-数值型  返回值-数值型
function sum(x: number, y: number): number {  
    return x + y;
}

​ 如果某变量可以是多种数据类型,我们可以用联合类型:

let age: (number | string); // age 可以是number  也可以是string
// 或者声明一个type类型
type Combinable = string | number;
let age: Combinable;

联合类型通常都与 null 或undefined一起使用:

const sayHello = (name: string | undefined) => {  };

sayHello("semlinker"); 
sayHello(undefined);

三、数据类型

​ TS中的数据类型除了JS中的数据类型,还新增了部分数据类型,总共有:any、string、number、boolean、null、undefined、object、bigint、symbol、元组、void等等,常用的数据类型有:any、string、number、boolean。

1、any

​ 在 TS 中 any 类型是顶级类型,任何类型的数据都可以被归类为any,如果我们讲一个变量的类型注解设置为any类型,那么TS允许我们给该变量赋任何类型的值,不受任何约束:

let a: any = 666;  // 类型注解为any
a = "Semlinker";  // 赋字符串
a = false; // 赋布尔值
a = 66 // 赋数字
a = undefined // undefined
a = null // null
a = [] // 数组
a = {} // 对象

​ 如果一个变量在声明的时候,没有设置类型注解,那系统会默认将其设置为 any 类型:

let something;
// 等价于
let something: any;

​ 虽然any使用起来很方便,但使用 any 就无法使用 TS提供的大量保护机制,所以我们要尽量减少any的使用,尽量明确变量的类型。

2、null和undefined

​ 在默认情况下,TS中的null和undefined是所有类型的子类型,也就是可以把 null和undefined赋值给任何类型的变量。

// null和undefined赋值给string
let str:string = "666";
str = null
str= undefined

// null和undefined赋值给number
let num:number = 666;
num = null
num= undefined

​ 但如果在TS的配置文件 tsconfig.json 中设置:"strictNullChecks":true,那 null和undefined就只能赋值给自己的类型,以及void类型。

3、number 和 bigint

​ 两者都表示数字,但是两者并不兼容,不能互相赋值。TS 中可以用 Number 表示的最大整数为 2^53 - 1,可以写为 Number.MAX_SAFE_INTEGER。如果超过了这个界限,可以用 BigInt来表示,它可以表示任意大的整数。

let big: bigint =  100n;
let num: number = 6;
big = num; // 不兼容 会报错
num = big;// 不兼容 会报错
4、Array

​ TS中定义数组的方式有两种:

// 数组名:元素类型[]
let arr:string[] = ["1","2"];
// 数组名:Array<元素类型>
let arr2:Array<string> = ["1","2"]

​ 当数组内的元素类型不止一种时,可以定义联合类型数组,或设置数组类型为 any:

// 数组元素可以为数字或字符串
let arr:(number | string)[];
// 数组元素为任意类型
let arr2:any[];

​ 还可以结合接口来指定对象成员的数组:

// interface是接口,后面会讲到
interface Arrobj{   
    name:string, 
    age:number
}
let arr3:Arrobj[]=[{name:'jimmy',age:22}]
5、Tuple(元组)

​ 元组是TS中特有的类型,定义方式类似于数组,就像被限制住元素个数、类型和顺序的数组:

// 定义元组 类型必须顺序匹配且个数必须为2
let x: [string, number]; 

x = ['hello', 10]; // OK 
x = ['hello', 10,10]; // 越界了 Error
x = [10, 'hello']; // 类型不匹配 Error

​ 元组中的元素可以通过下标访问,也可以通过解构赋值来访问元素:

// 定义元祖
let employee: [number, string] = [1, "Semlinker"];
// 数组下标访问
let n = employee[0];
// 解构赋值来访问元组元素  按顺序一一对应
let [id, username] = employee;
// 解构赋值数量不能多于元组的元素数量
let [id, username, age] = employee; // Error

​ 定义元组时,我们也可以通过在元素后面加 ? 来声明可选元素:

// 定义元组  第二个元素是可选元素
let optionalTuple: [string, boolean?];
// 赋值元组  两个元素都赋值
optionalTuple = ["Semlinker", true];
// 赋值元组  只赋值第一个元素  第二个可选元素不赋值
optionalTuple = ["Kakuqo"];

​ 定义元组时,元祖类型的最后一个元素可以表示剩余元素,以数组的形式存放多出来的元素,表示该元组是开放的,除了固定元素,可以有零个或多个额外的剩余元素:

// 定义元组 第二个元素是剩余参数 
// 这里的剩余参数只能是 string 类型  因为剩余参数数组是 string 数组
type RestTupleType = [number, ...string[]];
// 赋值元组 除了第一个值 剩下的都存放到 剩余参数数组中
let restTuple: RestTupleType = [666, "Semlinker", "Kakuqo", "Lolo"];

​ 在TS中,我们可以给元组加上 readonly 关键字,使其变为只读的,不允许进行修改:

// 声明只读类型的元组
const point: readonly [number, number] = [10, 20];
// 可读取
var n = point[0]
// 不可修改 
point[0] = 1; // 会报错 Cannot assign to '0' because it is a read-only property.
6、void

​ void 表示没有任何类型,赋值时只能赋予null 或 undefined。声明一个void类型的变量,没有任何意义,一般只用于当函数没有返回值时,才会用到void。

// 返回值类型定义为 void 表示没有返回值
function fun(): void {  
  console.log("this is TypeScript");
};
fun(); 
7、never

never类型表示的是那些永不存在的值的类型,一般用于两种情况:① 函数运行时抛出了异常,那么这个函数就永远不存在返回值,就是never。② 当函数中出现了死循环的代码,那么这个函数页永远不存在返回值,就是never。

never类型同nullundefined一样,也是任何类型的子类型,也可以赋值给任何类型。但是没有类型是never的子类型或可以赋值给never类型(除了never本身之外),即使any也不可以赋值给never

let ne: never;
let nev: never;
let an: any;

ne = 123; // Error
ne = nev; // OK
ne = an; // Error
8、unknown

​ unknown 与 any 类似,任何类型都可以赋值给它,两者唯一的区别在于:any类型的值,可以赋值给任何类型的变量,而 unknown 类型的值,只能赋值给 unknown 和 any 类型:

let notSure: unknown = 4;
let uncertain: any = notSure; // OK

let notSure: any = 4;
let uncertain: unknown = notSure; // OK

let notSure: unknown = 4;
let uncertain: number = notSure; // Error
9、object

​ object 表示的是所有非基本类型的数据,也就是不能把number、string、boolean、symbol等 基本类型赋值给 object,只能接收复杂数据类型:

let obj: object;
obj = 1; // error
obj = 'a'; // error
obj = true; // error
obj = null; // error
obj = undefined; // error
obj = {}; // ok

四、函数

1、函数声明
// 函数名(形参1: 数据类型,形参2: 数据类型): 返回值的数据类型
// x-数值型 y-数值型  返回值-数值型
function sum(x: number, y: number): number {  
    return x + y;
}
// 或
const sum = (x: number,y: number): number => {
    return x + y;
}
2、可选参数

​ 如果函数的部分参数,是非必须的,被称为可选参数,TS中通过在参数名后面加 ? 来标明,而且可选参数必须位于必需参数的后面:

// 可选参数 lastName?: string
function buildName(firstName: string, lastName?: string) { 
    if (lastName) {      
        return firstName + ' ' + lastName;   
    } else {     
        return firstName;   
    }
}
// 传递可选参数
let tomcat = buildName('Tom', 'Cat');  // Tom Cat
// 不传递可选参数
let tom = buildName('Tom'); // Tom
3、参数默认值

​ 在TS中可以给函数的参数设置默认值,如果使用函数时,未传递该参数,则使用默认值,如果传递了该参数,则传递的值覆盖默认值:

// 参数默认值 lastName: string = 'Cat'
function buildName(firstName: string, lastName: string = 'Cat') {   
    return firstName + ' ' + lastName;
}
// 传递lastName参数 覆盖默认值 
let tomcat = buildName('Tom', 'Cat222');  // Tom Cat222
let tom = buildName('Tom'); // Tom Cat
4、剩余参数

​ 在TS中如果不确定函数的参数数量,我们可以通过设置以数组+扩展运算符的方法来接收剩余参数,前面写的参数,会跟实参一一对应,剩下的参数会都会放到剩余参数数组中:

// 剩余参数 ...items: any[]
function push(array: any[], ...items: any[]) {   
    items.forEach(function(item) {     
        array.push(item);  
    });
}
let a = [];
// a 对应第一个参数array  剩余的参数都存放到 items 中 
push(a, 1, 2, 3);
5、函数重载

​ 函数重载是指使用相同名称和不同参数(数量或类型不同)、不同的返回值类型创建多个函数类型定义,它们不会被覆盖,只是为同一个函数体提供多个函数类型定义,这样就能根据传入的参数不同,确认不同的返回值类型:

// 联合类型 type
type Types = number | string
// 函数重载 1
function add(a:number,b:number):number;
// 函数重载 2
function add(a: string, b: string): string;
// 函数重载 3
function add(a: string, b: number): string;
// 函数重载 4
function add(a: number, b: string): string;
// 函数体
function add(a:Types, b:Types) {  
  if (typeof a === 'string' || typeof b === 'string') {  
    return a.toString() + b.toString(); 
  }  
  return a + b;
}
// 参数是两个 string 匹配函数重载2 返回值为 string
const result = add('Semlinker', ' Kakuqo');
// 可以调用string的内置API
result.split(' ');
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小朱同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值