TypeScriipt,字面意思就是JavaScript加个type来限制,就是这么简单。🥰
类型声明
- 手动类型声明 vs 自动类型判断
let a: number; // 类型声明
let a: number = 12; // 类型声明同时赋值
let a = 12; //当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型,可以省略掉类型声明
类型分类
类型 | 例子 | 描述 |
---|---|---|
number | 1, -33, 2.5 | 任意数字 |
string | ‘hi’, “hi” | 任意字符串 |
boolean | true、false | 布尔值true或false |
字面量 | 其本身 | 限制变量的值就是该字面量的值 |
any | - | 任意类型,使用any相当于关闭类型检查 |
unknown | - | 类型安全的any |
void | 空值(undefined) | 没有值(或undefined) |
never | 没有值 | 不能是任何值 |
object | {name:‘孙悟空’} | 任意的JS对象 |
array | [1,2,3] | 任意JS数组 |
tuple | [4,5] | 元素,TS新增类型,固定长度数组 |
enum | enum{A, B} | 枚举,TS中新增类型 |
其中tunple和enum为ts中特有类型(js中没有)
1、number string boolean:基本类型
需要注意:number包括整型和浮点型
// number
let a:number;
a = 12;
a = 12.1;
// string
let b: string;
b = 'hello world';
// boolean
let c: boolean;
c = true;
2、字面量与枚举enum:对值进行限制
字面量和枚举相同之处:直接对变量的“取值”范围进行限制,而不仅仅是变量的类型
- 字面量
let d: "male" | "female"; //限制d的值只能是这两个,“|” 表示或者的关系
d = "male";
let e = 1 | 2 | "hello world" ; //限制e的值只能是这3个
e = 1;
- 枚举
// 用关键字enum定义枚举类型Load_status
enum Load_status {
before_load = 0,
loading = 1,
loaded = "hi"
}
let ls: Load_status = Load_status.before_load // ls === 0 为真
3、any与unknown:哪个更推荐
- any:any类型相当于关闭了这个变量的类型检查,ts中应该尽量避免使用any
let d: any = 4;
d = 'hello';
d = true;
let e: number = 16;
e = d; // 不会报错,使用any带来了隐患
- unknown:当不确定啥类型的时候使用unknown,仅对自己关闭类型检查,但无法赋值给别的变量
let d: unknown = true;
d = 23;
let e: number = 16;
e = d; // 会报错,unknown无法赋值给其他变量
4、void与never:没有还是不存在
void常用于函数返回值类型,return;返回值为空
never为压根没有返回值,例如报错提前中断,压根不存在返回值
function sum(a:number):void{
console.log(a);
return;
}
function error(message: string): never {
throw new Error(message);
}
5、array与tuple:数组和元组的区别
- 数组array:同一个数组内元素类型必须相同,长度不固定,
const arr: number[] = [1,2,3,4];
const arr: Array<number>;
// 二维数组
var multi:number[][] = [[1,2,3],[23,24,25]];
console.log(multi[0][0]);
- 元组tuple:同一元组内元素的类型可不同,长度固定
let x: [string, number?]; //number?表示元素是可选的,可选元素放最后
x = ["hello", 10];
x = ["hello"];
x = [10, "hello"]; // 错误
6、object:用接口限制对象与类
使用接口interface定义对象
let obj:object = {}; //没啥用,没对类型进行限制,
// 用接口限制对象
interface Person {
name : string ,
readonly age: number, //只读属性,不可修改
gender ? : string,
[propName: string]: any;
}
let obj : Person = {
name : 'zhangsan' ,
age : 25,
}
7、类:实例的类型,接口的实现
类“实现”(implements )接口
类的实例的类型为类
// 定义接口
interface Person{
name: string;
sayHello():void;
}
// 类“实现”接口
class Student implements Person{
constructor(public name: string) {
}
sayHello() {
console.log('大家好,我是'+this.name);
}
}
// 类的实例的类型为类
let st:Student = new Student("myName");
8、type:关键字,用于自定义类型
- 使用type关键字来自定义类型
type myType = number | string;
let a: myType = "hello";
a = 12;
9、Generic:泛型
- 使用泛型<T>来定义函数/类中用到的类型
function fn<T>( a: T):T{
return a;
}
class Person<T,K>{
_name: T;
_age: K;
constructor(name: T, age: K){
this._name = name;
this._age = age;
}
}
类型断言(我来告诉编译器)
使用场景:人知道变量的类型,但是ts编译器不知道。此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式
let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length; // 方式1
let strLength: number = (<string>someValue).length; // 方式2
运算符( | & ? … =) 整起来那叫一个高大上
| 表示或者 ; &表示并且
/**
* 多个类型用连接符连接
* |:表示或者,满足任意一个类型
* &:表示且,同时满足
*/
let k: { name: string } & { age: number } & { [propName: string]: any };
k = { name: 'xxiao', age: 12, gender: Gender.Female }
? 表示可以选择, …表示解构,=表示默认值
/**
* 表示
* ?:表示该参数可选,可有可无
* ...:用于解构数组和对象
* =:表示默认值
*/
function fn(a:number, b?: string ):void{};
function fn(a:number, b: string = '123' ):void{};
const tupleList: [...number[], string] = [1, 2, "ss"]
ts学习资料推荐
视频课程推荐B站尚硅谷李立超老师的课
本文是学习该课程笔记的基础上,添加了很多案例,并对容易混淆的概念进行区分
速速马住!