TypeScript 原始类型、函数、接口、类、泛型 基础总结
原始数据类型
原始数据类型包括:
Boolean
String
Number
Null
undefined
类型声明是TS非常重要的一个特点,通过类型声明可以指定TS中变量、参数、形参的类型。
Boolean 类型
let boolean: boolean = true boolean = false boolean = null // bollean = 123 报错不可以将数字 123 赋值给 boolean类型的变量 复制代码
Number 类型
//ES6 Number 类型 新增支持2进制和8进制 let num: number = 123 num = 0b1111 复制代码
String 类型
let str1: string = 'hello TS' let sre2: string = `模板字符串也支持使用 ${str1}`] 复制代码
Null 和 Undefined
let n: null = null let u: undefined = undefined n = undefined u = null // undefined 和 null 是所有类型的子类型 所以可以赋值给number类型的变量 let num: number = 123 num = undefined num = null 复制代码
any 类型
any 表示队变量没有任何显示,编译器失去了对 TS 的检测功能与 JS 无异(不建议使用)。
let notSure: any = 4 // any类型可以随意赋值 notSure = `任意模板字符串` notSure = true notSure = null // 当 notSure 为any 类型时,在any类型上访问任何属性和调用方法都是允许的, 很有可能出现错误 notSure.name // 现在调用name属性是允许的,但很明显我们定义的notSure没有name这个属性,下面的调用sayName方法也是如此 notSure.sayName() 复制代码
array 类型
// 数组类型,可以指定数组的类型和使用数组的方法和属性 let arrOfNumbers: number[] = [1, 2, 3] console.log(arrOfNumbers.length); arrOfNumbers.push(4) 复制代码
tuple 元组类型
// 元组类型 元组就是固定长度,类型的数组 // 类型和长度必须一致 let u: [string, number] = ['12', 12] // let U: [string, number] = ['12', 12, true] 报错信息为:不能将类型“[string, number, boolean]”分配给类型“[string, number]”。源具有 3 个元素,但目标仅允许 2 个。 // 也可以使用数组的方法,如下所示push一个值给元组u u.push(33) 复制代码
Interface 接口
对对象的形状(shape)进行描述
Duck Typing(鸭子类型)
interface Person { // readonly id 表示只读属性的id不可以修改 readonly id: number; name: string; age: number; // weight? 表示可选属性,可以选用也可以不选用 weight?: number } let host: Person = { id: 1, name: 'host', age: 20, weight: 70 } //host.id = 2 报错 提示信息为:无法分配到 "id" ,因为它是只读属性 复制代码
function 函数类型
// 方式一:函数声明的写法 z 为可选参数 , function add1 (x: number, y: number, z?: number): number { if (typeof z === 'number') { return x + y + z } else { return x + y } } // 需要注意的是:可选参数必须置于所有必选参数之后,否则会报错 add1(1, 2, 3) // 方式二:函数表达式 const add2 = (x: number, y: number, z?: number): number => { if (typeof z === 'number') { return x + y + z } else { return x + y } } // 使用interface接口 描述函数类型 interface ISum { (x: number, y: number, z?: number): number } let add3: ISum = add1 复制代码
值的注意的是:可选参数必须置于所有必选参数之后,否则会报错,如下图展示的错误案例所示:·
类型推论
当定义变量时没有指定类型,编译器会自动推论第一次赋的值为默认类型
let s = 'str' // s = 12 本句将会报错,提示为:不能将类型“number”分配给类型“string” 复制代码
联合类型
使用 |
分隔可选类型
let StringOrNumber: string | number StringOrNumber = 123 StringOrNumber = '111' 复制代码
类型断言
使用 as
关键字进行类型断言
function getLength (rod: number | string): number { const str = rod as string //这里我们可以用 as 关键字,告诉typescript 编译器,你没法判断我的代码,但是我本人很清楚,这里我就把它看作是一个 string,你可以给他用 string 的方法。 if (str.length) { return str.length } else { const num = rod as number return num.toString().length } } 复制代码
类型守卫
// 4.类型守卫 type guard typescript 在不同的条件分支里面,智能的缩小了范围 function getLength2 (rod: number | string): number { if (typeof rod === 'string') { return rod.length } else { // else 里面的rod 会自动默认为number类型 return rod.toString().length } } 复制代码
Class 类
面向对象编程的三大特点:
封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,
继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性。
多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。
话不多少,看代码:
class Animal { readonly name: string constructor(name: string) { this.name = name console.log(this.run()) } // private run ():私有的 protected run () 受保护的 run () { return `${this.name} is running` } } const animal = new Animal('elephant') // console.log(animal.name) animal.run() //elephant is running // 继承 class Dog extends Animal { age: number constructor(name, age) { super(name) console.log(this.name) this.age = age } bark () { console.log(`这只在叫的狗狗叫${this.name},它今年${this.age}岁了`) } } const dog = new Dog('旺财', 5) dog.run() // 旺财 is running dog.bark() // 这只在叫的狗狗叫旺财,它今年5岁了 // 多态 class Cat extends Animal { static catAge = 2 constructor(name) { super(name) console.log(this.name) // 布丁 } run () { return 'Meow,' + super.run() } } const cat = new Cat('布丁') console.log(cat.run()) // Meow,布丁 is running console.log(Cat.catAge) // 2 复制代码
class中还提供了readonly关键字,readonly为只读属性,在调用的时候不能修改。如下所示:
类成员修饰符
public修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是public的。
private修饰的属性或方法是私有的,不能在声明它的类的外部访问。
上述示例代码中,在父类Animal的 run 方法身上加上private修饰符之后就会产生如下图的报错信息:
protected 修饰的属性或方法是受保护的,它和private类似,区别在于它在子类中也是可以访问的。
上述示例代码中,在父类Animal的 run 方法身上加上protected修饰符之后就会产生如下图的报错信息:
接口和类
类可以使用 implements来实现接口。
// interface可以用来抽象验证类的方法和方法 interface Person { Speak (trigger: boolean): void; } interface Teenagers { Young (sge: number): void } // 接口之间的继承 interface PersonAndTeenagers extends Teenagers { Speak (trigger: boolean): void; } // implements 实现接口 class Boy implements Person { Speak (mouth: boolean) { } } // class Girl implements Person, Teenagers 和 class Girl implements PersonAndTeenagers 作用相同 class Girl implements PersonAndTeenagers { Speak (mouth: boolean) { } Young (sge: number) { } } 复制代码
enum枚举
枚举成员会被赋值为从 0
开始递增的数字,同时也会对枚举值到枚举名进行反向映射:
enum Color { red = 'red', blue = 'blue', yellow = 'yellow', green = 'green' } // 常量枚举 const enum Color { red = 'red', blue = 'blue', yellow = 'yellow', green = 'green' } console.log(Color.red) // 0 // 反向映射 console.log(Color[0]) // red const value = 'red' if (value === Color.red) { console.log('Go Go Go ') 复制代码
常量枚举经过编译后形成的js文件如下:
非常量枚举经过编译器编译之后的js文件如下:
Generics 泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
约束泛型
类与泛型
接口与泛
示例代码如下:
function echo (arg) { return arg } let result1 = echo(123) // 参数传递123后result1 的类型为any // 泛型 function echo2<T> (arg: T): T { return arg } let result2 = echo2(123) // 加上泛型之后 参数传递 123后result2的类型为number function swap<T, U> (tuple: [T, U]): [U, T] { return [tuple[1], tuple[0]] } console.log(swap(['hero', 123]))//[ 123, 'hero' ] // 约束泛型 interface IWithLength { length: number } function echoWithLength<T extends IWithLength> (arg: T): T { console.log(arg.length) return arg } const str = echoWithLength('123') const obj = echoWithLength({ length: 3, name: 'Tom' }) const arr = echoWithLength([1, 2, 3, 4]) // 类与泛型 class Queue<T> { private data = [] push (item: T) { return this.data.push(item) } pop (): T { return this.data.shift() } } const queue = new Queue<number>() queue.push(1) console.log(queue.pop().toFixed())// 1 // 接口与泛型 interface KeyPair<T, U> { key: T value: U } let kp1: KeyPair<string, number> = { key: 'str', value: 123 } let kp2: KeyPair<number, string> = { key: 123, value: 'str' } let arr2: Array<string> = ['1', '2'] // 使用 Array<string> 等价于 interface Array<T> 复制代码
类型别名 type-alias
类型别名,就是给类型起一个别名,让它可以更方便的被重用。
let sum: (x: number, y: string) => number const result1 = sum(1, '2') // 将(x: number, y: string) => number类型取一个别名 为 PlusType type PlusType = (x: number, y: string) => number let sum2: PlusType const result2 = sum2(2, '2') type StrOrNum = string | number let result3: StrOrNum = 123 result3 = '123' 复制代码
字面量
let Name: 'name' = 'name' // Name = '123' //报错信息:不能将类型“"123"”分配给类型“"name"” let age: 19 = 19 type Directions = 'Up' | 'Down' | 'Left' | 'Right' let up: Directions = 'Up' 复制代码
交叉类型
// 交叉类型 使用 ‘&’ 符号进行类型的扩展 interface IName { name: string } type IPerson = IName & { age: number } let person: IPerson = { name: 'Tom', age: 19 } 复制代码
内置类型
全局对象
// global objects 全局对象 const a: Array<string> = ['123', '456'] const time = new Date() time.getTime() const reg = /abc/ // 此时reg为RegExp类型 reg.test('abc') 复制代码
build-in object 内置对象
Math.pow(2, 2) //返回 2 的 2次幂。 console.log(Math.pow(2, 2)) // 4 复制代码
DOM and BOM
// document 对象,返回的是一个 HTMLElement let body: HTMLElement = document.body // document 上面的query 方法,返回的是一个 nodeList 类型 let allLis = document.querySelectorAll('li') //当然添加事件也是很重要的一部分,document 上面有 addEventListener 方法,注意这个回调函数,因为类型推断,这里面的 e 事件对象也自动获得了类型,这里是个 mouseEvent 类型,因为点击是一个鼠标事件,现在我们可以方便的使用 e 上面的方法和属性。 document.addEventListener('click', (e) => { e.preventDefault() }) 复制代码
utility types实用类型
interface IPerson2 { name: string age: number } let viking: IPerson2 = { name: 'viking', age: 20 } // partial,它可以把传入的类型都变成可选 type IPartial = Partial<IPerson> let viking2: IPartial = {} // Partial 将IPerson 中的类型变成了可选类型 所以 viking2 可以等于一个空对象 // Omit,它返回的类型可以忽略传入类型的某个属性 type IOmit = Omit<IPerson2, 'name'> // 忽略name属性 let viking3: IOmit = { age: 20 } 复制代码
如果加上name属性将会报错:不能将类型“{ age: number; name: string; }”分配给类型“IOmit”。对象文字可以只指定已知属性,并且“name”不在类型“IOmit”中。
伪原创工具 SEO网站优化 https://www.237it.com/
作者:不一213
链接:https://juejin.cn/post/7035563509882552334