TypeScript 基本类型
一、环境准备
- ts和js的区别
- ts 属于静态类型,写代码时就能检查错误。是js的超类,包含js功能,多的是类型。
- js 属于动态类型,只有在运行时才会报错,不会检查类型是否发生变化。
- typescript 语言是 javascript 扩展而来的一个超集。typescript 的语法检查能帮助提高编程的效率和减少出错率,因此在前端技术中被广泛运用。
- 安装与测试
$ npm i -g typescript
added 1 package, and audited 2 packages in 3s
found 0 vulnerabilities
## 测试是否安装成功
$ tsc -v
Version 4.8.4
- 代码,新建文件:hello.ts
console.log('hello,中国')
let a = 1;
let b = a.toFixed(2);
console.log(a, b);
# a是数字,会变色,b是字符串,不会变色。
$ node hello.ts
hello,中国
1 1.00
- 编译和运行
# 编译,会生成hello.js
$ tsc hello.ts
# 运行
$ node hello.js
hello,中国
- 简化ts运行步骤
# 安装ts-node
$ npm i -g ts-node
added 19 packages, and audited 20 packages in 3s
found 0 vulnerabilities
$ ts-node -v
v10.9.1
# 运行,但不会生成hello.js
$ ts-node hello.ts
hello,中国
# 或用 node 执行,requier ts-node,他会把代码当做js来运行,所有当有类型约束时,此命令会报错。
$ node hello.ts
二、vs code 无法执行 ts-node命令
$ tsc --init
tsc : 无法加载文件 D:\nodejs\tsc.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
所在位置 行:1 字符: 1
+ tsc --init
+ ~~~
+ CategoryInfo : SecurityError: (:) [],PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
- 解决方法:
- 以管理员身份运行 vscode
- 执行:get-ExecutionPolicy,会显示 Restricted,表示状态是禁止的;
- 执行:set-ExecutionPolicy RemoteSigned
- 再次执行:get-ExecutionPolicy,会显示 RemoteSigned,表示状态是允许的;
三、各种类型
- 为变量添加类型约束
- :为类型注解
- | 为联合类型
- & 交叉类型 两个类型的合并
- Object:所有类型的基类,可以赋值任何类型;object只能赋值引用类型,赋值基本类型会报错。{}相当于new Object,可以是任意类型
- 类型别名:当一种类型被多次使用时
- 函数类型
- 箭头函数
- 可选参数,只能出现在参数列表的最后,在可传可不传的参数后面加上问号
// js 原有类型
let age: number = 1;
let myName: string = "123";
let isSuccess: boolean = true;
let a: null = null;
let b: undefined = undefined;
let s: symbol = Symbol();
// object 类型
let nums: number[] = [1, 3, 4, 4.1];
let namesShu: string[] = ["张飞", "关羽", "刘备"];
// 不推荐下面这种写法
let namesWei: Array<string> = ["曹操", "曹丕", "曹植"];
// 联合类型
let arr: (string | number)[] = ["a", "b", "c", 1, 2, 3];
// 交叉类型
interface People {
age: number,
height: number
}
interface Man{
sex: string
}
const xiaoman = (man: People & Man) => {
console.log(man.age)
console.log(man.height)
console.log(man.sex)
}
xiaoman({age: 18,height: 180,sex: 'male'});
// 多维数组
let amount:number[][]=[[1,2,3],[4]]
let amount2:Array<Array<number>>=[[1,2,3],[4]]
// 类型别名:当一种类型被多次使用时
type custom = (string | number)[];
let arr2: custom = ['a', 'b', 'c', 1, 2, 3];
// 函数类型,指定参数和返回值的类型
function add(num1: number, num2: number): number {
return num1 + num2;
}
console.log(`2 + 6 = ${add(2, 6)}`);
// 箭头函数
const muli = (a: number, b: number): number => {
return a * b;
};
console.log(`2 x 6 = ${muli(2, 6)}`);
// 另一种函数类型 (num1: number, num2: number)=> number 为一种类型
const division: (num1: number, num2: number) => number = (a, b) => {
return a / b;
};
console.log(`12 ÷ 6 = ${division(12, 6)}`);
// 没有返回值
const sayName: (name: string) => void = (n) => {
console.log(`${n},你好`);
};
sayName("李四");
// 可选参数
const mySlice: (start?: number, end?: number) => void = (s, e) => {
console.log("开始索引", s, "结束", e);
};
mySlice(1);
mySlice(1, 2);
mySlice();
// 返回
hello,中国
2 + 6 = 8
2 x 6 = 12
12 ÷ 6 = 2
李四,你好
开始索引 1 结束 undefined
开始索引 1 结束 2
开始索引 undefined 结束 undefined
// 可变参数
const add=(...args:number[]):number=>{
let sum=0
args.forEach(v=>{
sum+=v;
})
return sum;
}
console.log(add(1,2,34,5));
四、复杂类型
4.1 对象
let person: { name: string; age: number } = {
name: '李四',
age: 20,
}
console.log(person)
let person: { name: string; age: number; sayHi: (name: string) => void } = {
name: '李四',
age: 20,
sayHi: (a) => {
console.log(`sayHi,${a}`)
},
}
console.log(person.name)
console.log(person.age)
person.sayHi('刘备')
// 任意类型
interface Person{
name:string,
age?:number,
[a:string]:any
}
let p:Person={
name:"张三",
abc:123
}
4.2 接口与继承
- 接口只能为对象指定类型
- 类型可以为对象指定类型,也可以为任意类型指定别名 type n=number|string
interface Person {
name: string
age: number
}
interface Person2 extends Person {
hobby?: string
}
let p: Person2 = {
name: '张三',
age: 10,
hobby: '下棋',
}
console.log(p)
4.3 元组
- 什么时候用元组:确切的知道元素个数和类型的情况下
- 坐标数据
- 元组数据可以确切的标出数组的元素个数,以及每个类型
let point: [number, number] = [39.24, 28.76]
console.log(point)
4.4 类型推论
- 由系统去推断类型
- 声明变量,并且立即初始化时,可用。
- 推荐一定要为参数指定类型
- 如果不知道返回值类型,鼠标放上,就可以显示
let year = 2022
let point = [39.24, 28.76]
console.log(point)
function func(a: number, b: number) {
return a + b
}
4.5 类型断言
- 来指定具体的类型
- as 关键字 ,后面跟一个更加具体的类型
- 这样就有a标签特有的属性了
- 选中一个元素,在控制台输入console.dir($0),查看 Prototype 属性,即可查到该元素的类型
let aLink = document.getElementById('#link') as HTMLAnchorElement
let href = aLink.href
4.6 字面量类型
- 常用来表示一些明确的可选值类型
// str1 类型为string
let str1 = 'Hello Ts'
// str1 类型为Hello Ts ,这个就是字面量类型
const str2 = 'Hello Ts'
// 参数只能是这几个中的任意一个。优势:更加严谨
function changeDirection(direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction)
}
changeDirection('down')
// 输出:down
4.7 枚举类型
- 首字母大写,以逗号分割
- 是有值的,默认从0开始,也可以手动给每个值设置,也可以给第一个设置初始值,后面会按顺序递增
- 字符串枚举,没有自增行为,必须给每个成员有初始值
enum Dir {
Up,
Down,
Left,
Right,
}
function changeDirection2(direction: Dir) {
console.log(direction)
}
changeDirection2(Dir.Down)
// 输出:1
enum Dir2 {
Up = 10,
Down,
Left,
Right,
}
enum Dir3 {
Up = 2,
Down = 4,
Left = 6,
Right = 8,
}
enum Dir4 {
Up = '向上',
Down = '向下',
Left = '向左',
Right = '向右',
}
4.8 any类型
- 不建议用
- 失去了类型检查和代码提示
4.9 typeof
- 用来获取类型
- 类型上下文
let p1 = { a: 1, b: 2 }
function add(point: typeof p1) {
return point.a + point.b
}
console.log(add(p1))
console.log(add({ a: 8, b: 19 }))
let a: typeof p1.a
a = 90
let a: typeof p1.a = 90
世界上没有什么事情是跑步解决不了的,如果有,那就再跑一会!