一、typescript基础类型
1.TypeScript 简介
TS是JS的超集,所以JS基础的类型都包含在内
基础类型:Boolean、Number、String、null、undefined 以及 ES6 的 Symbol 和 ES10 的 BigInt。
2.学习 TS 必须要知道的命令
# 起步安装
npm install typescript -g
# 创建 TS 配置文件
tsc --init
# 实时编译 会在同文件夹下创建同名 JS 文件
tsc -w
# 用 node 运行 TS 编译后生成的 JS 文件
node index.js
# 编译 TS 文件为 JS 文件
tsc 文件名
# nodejs 环境执行ts
npm i @types/node --save-dev #(node环境支持的依赖必装)
# 安装
npm i ts-node --g
# 编译并同时运行 TS 文件
ts-node 文件名
3.字符串类型
let a: string = '123'
// 普通声明
// 也可以使用es6的字符串模板
let str: string = `dddd${a}`
其中用来定义 [ES6 中的模板字符串],${expr} 用来在模板字符串中嵌入表达式。
4.数字类型
支持十六进制、十进制、八进制和二进制;
let notANumber: number = NaN; // Nan
let num: number = 123; // 普通数字
let infinityNumber: number = Infinity; // 无穷大
let decimal: number = 6; // 十进制
let hex: number = 0xf00d; // 十六进制
let binary: number = 0b1010; // 二进制
let octal: number = 0o744; // 八进制
5.布尔类型
注意,使用构造函数 Boolean 创造的对象不是布尔值:
let createdBoolean: boolean = new Boolean(1)
// 这样会报错
// 因为事实上 new Boolean() 返回的是一个 Boolean 对象
事实上 new Boolean() 返回的是一个 Boolean 对象 需要改成
let createdBoolean: Boolean = new Boolean(1)
let booleand: boolean = true // 可以直接使用布尔值
let booleand2: boolean = Boolean(1) // 也可以通过函数返回布尔值
6.空值类型
JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数
function voidFn(): void {
console.log('test void')
}
void 类型的用法,主要是用在我们不希望调用者关心函数返回值的情况下,比如通常的异步回调函数
void也可以定义undefined 和 null类型
let u: void = undefined
let n: void = null;
7.Null和undefined类型
let u: undefined = undefined; // 定义undefined
let n: null = null; // 定义null
void 和 undefined 和 null 最大的区别: 与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 string 类型的变量:
// 这样写会报错 void类型不可以分给其他类型
let test: void = undefined
let num2: string = "1"
num2 = test
// 这样是没问题的
let test: null = null
let num2: string = "1"
num2 = test
// 或者这样的
let test: undefined = undefined
let num2: string = "1"
num2 = test
TIPS 注意: 如果你配置了tsconfig.json 开启了严格模式
{
"compilerOptions":{
"strict": true
}
}
null 不能赋予 void 类型
二、任意类型
1.any 类型
没有强制限定哪种类型,随时切换类型都可以 我们可以对 any 进行任何操作,不需要检查类型
let anys:any = 123
anys = '123'
anys = true
声明变量的时候没有指定任意类型默认为any
let anys;
anys = '123'
anys = true
弊端如果使用any 就失去了TS类型检测的作用
2.unknown 顶级类型
TypeScript 3.0中引入的 unknown 类型也被认为是 top type ,但它更安全。与 any 一样,所有类型都可以分配给unknown
unknow类型比any更加严格当你要使用any 的时候可以尝试使用unknow
// unknown 可以定义任何类型的值
let value: unknown;
value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = null; // OK
value = undefined; // OK
value = Symbol("type"); // OK
// 这样写会报错 unknow 类型不能作为子类型只能作为父类型 any 可以作为父类型和子类型
// unknown 类型不能赋值给其他类型
let names:unknown = '123'
let names2:string = names
// 这样就没问题 any 类型是可以的
let names:any = '123'
let names2:string = names
// unknown 可赋值对象只有 unknown 和 any
let bbb:unknown = '123'
let aaa:any= '456'
aaa = bbb
区别2
// 如果是 any 类型在对象没有这个属性的时候还在获取是不会报错的
let obj:any = {b:1}
obj.a
// 如果是 unknow 是不能调用属性和方法
let obj:unknown = {b:1,ccc:():number=>213}
obj.b
obj.ccc()
三、接口和对象类型
1.对象的类型
在 TypeScript 中,我们定义对象的方式要用关键字 interface(接口),我的理解是使用 interface 来定义一种约束,让数据的结构满足约束的格式。定义方式如下:
// 这样写是会报错的 因为我们在person定义了a,b但是对象里面缺少b属性
// 使用接口约束的时候不能多一个属性也不能少一个属性
// 必须与接口保持一致
interface Person {
b:string,
a:string
}
const person:Person = {
a:"213"
}
// 重名interface 可以合并
interface A{name:string}
interface A{age:number}
var x:A={name:'xx',age:20}
// 继承
interface A{
name:string
}
interface B extends A{
age:number
}
let obj:B = {
age:18,
name:"string"
}
2.可选属性 使用 ? 操作符
// 可选属性的含义是该属性可以不存在
// 所以说这样写也是没问题的
interface Person {
b?:string,
a:string
}
const person:Person = {
a:"213"
}
3.任意属性 [propName: string]
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
// 在这个例子当中我们看到接口中并没有定义C但是并没有报错
// 应为我们定义了[propName: string]: any;
// 允许添加新的任意属性
interface Person {
b?:string,
a:string,
[propName: string]: any;
}
const person:Person = {
a:"213",
c:"123"
}
4.只读属性 readonly
readonly 只读属性是不允许被赋值的只能读取
// 这样写是会报错的
// 应为a是只读的不允许重新赋值
interface Person {
b?: string,
readonly a: string,
[propName: string]: any;
}
const person: Person = {
a: "213",
c: "123"
}
person.a = 123
5.添加函数
interface Person {
b?: string,
readonly a: string,
[propName: string]: any;
cb:()=>void
}
const person: Person = {
a: "213",
c: "123",
cb:()=>{
console.log(123)
}
}
四、数组类型
1.基础写法[ ]
// 类型加中括号
let arr:number[] = [123]
// 这样会报错定义了数字类型出现字符串是不允许的
let arr:number[] = [1,2,3,'1']
// 操作方法添加也是不允许的
let arr:number[] = [1,2,3,]
arr.unshift('1')
var arr: number[] = [1, 2, 3]; // 数字类型的数组
var arr2: string[] = ["1", "2"]; // 字符串类型的数组
var arr3: any[] = [1, "2", true]; // 任意类型的数组
2.数组泛型
// 规则 Array<类型>
let arr:Array<number> = [1,2,3,4,5]
3.用接口表示数组
// 一般用来描述类数组
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
// 表示:只要索引的类型是数字时,那么值的类型必须是数字。
4.多维数组
let data:number[][] = [[1,2], [3,4]];
5.arguments类数组
function Arr(...args:any): void {
console.log(arguments)
// 错误的arguments 是类数组不能这样定义
let arr:number[] = arguments
}
Arr(111, 222, 333)
function Arr(...args:any): void {
console.log(arguments)
// ts内置对象IArguments 定义
let arr:IArguments = arguments
}
Arr(111, 222, 333)
// 其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}
6.any 在数组中的应用
// 一个常见的例子数组中可以存在任意类型
let list: any[] = ['test', 1, [],{a:1}]
五、函数扩展
1.函数的类型
// 注意,参数不能多传,也不能少传 必须按照约定的类型来
const fn = (name: string, age:number): string => {
return name + age
}
fn('张三',18)
2.函数的可选参数?
// 通过?表示该参数为可选参数
const fn = (name: string, age?:number): string => {
return name + age
}
fn('张三')
3.函数参数的默认值
const fn = (name: string = "我是默认值"): string => {
return name
}
fn()
4.接口定义函数
//定义参数 num 和 num2 :后面定义返回值的类型
interface Add {
(num: number, num2: number): number
}
const fn: Add = (num: number, num2: number): number => {
return num + num2
}
fn(5, 5)
interface User{
name: string;
age: number;
}
function getUserInfo(user: User): User {
return user
}
5.定义剩余参数
const fn = (array:number[],...items:any[]):any[] => {
console.log(array,items)
return items
}
let a:number[] = [1,2,3]
fn(a,'4','5','6')
6.函数重载
重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。
如果参数类型不同,则参数类型应设置为 any。
参数数量不同你可以将不同的参数设置为可选。
function fn(params: number): void
function fn(params: string, params2: number): void
function fn(params: any, params2?: any): void {
console.log(params)
console.log(params2)
}
fn(123)
fn('123',456)