简介介绍<br>
简介<br>
TypeScript 是 Microsoft 开发和维护的一种面向对象的编程语言。它是 JavaScript 的超集,包含了 JavaScript 的所有元素,可以载入 JavaScript 代码运行,并扩展了 JavaScript 的语法。
Typescript特点
1、TypeScript是JavaScript的超集,具有可选的类型并可以编译为纯JavaScript。
2、增加了静态类型、类、模块、接口和类型注解<br>
3、可用于开发大型的应用,便于大型、复杂程序维护、可复用性高、易于扩展重构
4、通过类型注解提供编译时的静态类型检查,提升开发效率
5、相对于Javascript学习成本比较高、代码编写量会相对比JavaScript多
Typescript优势
1. 静态输入
静态类型化是一种功能,可以在开发人员编写脚本时检测错误。查找并修复错误是当今开发团队的迫切需求。有了这项功能,就会允许开发人员编写更健壮的代码并对其进行维护,以便使得代码质量更好、更清晰。
2. 大型的开发项目
有时为了改进开发项目,需要对代码库进行小的增量更改。这些小小的变化可能会产生严重的、意想不到的后果,因此有必要撤销这些变化。使用TypeScript工具来进行重构更变的容易、快捷。
3. 更好的协作
当发开大型项目时,会有许多开发人员,此时乱码和错误的机也会增加。类型安全是一种在编码期间检测错误的功能,而不是在编译项目时检测错误。这为开发团队创建了一个更高效的编码和调试过程。
4. 更强的生产力
干净的 ECMAScript 6 代码,自动完成和动态输入等因素有助于提高开发人员的工作效率。这些功能也有助于编译器创建优化的代码。
*基础类型
boolean<br>
const a:boolean=true<br>
number
const:number=12<br>
string
const a:string='test'<br>
array
const a:string[]=['name', '12']<br>
const b:number[] = [1,2,3]<br>
const c:(string|number)[] = [1, '22']<br>
tuple
const a:[string, number] = ['name', 12]<br>
enum
any
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。
void
某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void
null和undefined
是所有类型的子类型。 就是说可以把 null和undefined赋值给number类型的变量。
never
1、never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。
2、类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。
3、任意类型和never的交叉类型都是never,任意类型和never的联合类型都是其本身
示例:<br>type Filter<T, U> = T extends U ? T : never<br>type R = Filter<'a' | 2 | false | 'b', string> // R = 'a'|'b' 从类型中过滤出string类型的字段<br>// Fliter 最终会解析成下面这样,在通过条件类型判断过滤出最终数据<br>type R = <br>| ('a' extends string ? 'a':never) <br>| (2 extends string ? 2:never) <br>| (false extends string ? false:never) <br>| ('b' extends string ? 'b':never)<br><br>
object
object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型
unknown
概念
unknown是所有类型的父类型,任何类型都是unknown的子类型。
特点
1、任何类型的实例都可以分配给unknown
let a:unknown<br>a = 1<br>a = 'a'<br>...<br>
2、unknown只能分配给unknown,不能分配给其他任何类型
let a:unknown<br>let b: string = a // 错误<br>
3、任意类型和unknown的交叉类型都是其本身
type T = string & unknown // string<br>type T1 = number & unknown // number<br>type T2 = boolean & unknown // boolean<br>...<br>
4、任意类型和unknown的联合类型都是unknown
type T = string | unknown // unknown<br>type T1 = number | unknown // unknown<br>...<br>
类型断言<br>
1、使用关键字 as<br>
const a: string | number = '' (a as string).slice()<br>
2、使用尖括号<> <string>a.slice()<br>
3、非空断言 ! const a: number| null| undefined=0<br> const b = a!.toFixed(2) <br>
4、双重断言 <br>interface Person {<br> name: string<br> age: number<br>}<br>const student: Person = 'jack' as unknown as Person
注意事项
TypeScript中any,never,unknown和viod有什么区别?
1、unknown类型和any类型类似。与any类型不同的是unknown类型可以接受任意类型赋值,但是unknown类型赋值给其他类型前,必须被断言
2、never,never表示永远不存在的类型。比如一个函数总是抛出错误,而没有返回值。或者一个函数内部有死循环,永远不会有返回值。函数的返回值就是never类型。
3、void, 没有显示的返回值的函数返回值为void类型。如果一个变量为void类型,只能赋予undefined或者null。
*泛型<br>
特点:泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,增强了代码可复用性<br>
<br>
*高级类型
交叉类型(&)
交叉类型是将多个类型合并为一个类型 T&U&K<br>
联合类型(|)
申明多个类型 T | K<br>
类型保护与区分类型
在多类型情况下访问某一类型,ts机制会检测报错。只有访问多类型共同的属性才可以<br>
方式
使用类型断言
用户自定义的类型保护
示例:function isFish(pet: Fish | Bird): pet is Fish {<br> return (<Fish>pet).swim !== undefined;<br>}
注:pet is Fish就是类型谓词 NodeJS.Timer<br>
typeof类型保护
instanceof类型保护
可辨识联合
概念
1、你可以合并单例类型,联合类型,类型保护和类型别名来创建一个叫做可辨识联合的高级模式,它也称做标签联合或代数数据类型。 可辨识联合在函数式编程很有用处。
索引类型(keyof)
索引类型操作符 keyof T<br>
示例1:<br>function getObjVal<T extends Object, U extends keyof T>(obj: T, key: U): T[U] {<br> return obj[key]<br>}<br><br>const person = {name:'zhangsan', age: 12}<br>getObjVal(person, 'name') // zhangsan<br><br>示例2:function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {<br> return names.map(n => o[n]);<br>}<br><br>interface Person {<br> name: string;<br> age: number;<br>}<br>let person: Person = {<br> name: 'Jarid',<br> age: 35<br>};<br>let strings: string[] = pluck(person, ['name']); // ok, string[]
类型别名(type)
type Alias = T | U
类型约束(extends)<br>
type BaseType = string | number | boolean<br><br>// 这里表示 copy 的参数<br>// 只能是字符串、数字、布尔这几种基础类型<br>function copy<T extends BaseType>(arg: T): T {<br> return arg<br>}
条件类型(U ? X : Y)<br>
T extends U ? X : Y 如果 T 是 U 的子集(T能够赋值给U),就是类型 X,否则为类型 Y。 <br>
剔除null、undefined type Diff<T, U> = T extends U ? never : T
内置的常用高级类型
Omit 去除类型中某些项 Omit<T,key> <br>
Pick 选取类型中指定类型 Pick<T, key1 | key2><br>
Partial 类型中所有选项变为可选 Paartial<T><br>
Required 将类型中所有选项变为必选 Required<T><br>
Exclude Exclude<keyof T, keyof U> 返回 T 在 U中不存在的类型。与Extract相反
Record 利用已有的类型,创建新属性的映射类型 Record<string|number|symbol, T><br>type person6 = Record<'name' | 'age', string><br>// person6 === {name: string; age: string} const obj:Record<string, any> = ref({})<br>参考:https://zhuanlan.zhihu.com/p/356662885
ReturnType<(s: string) => void> // void 获取函数返回的类型<br>参考:https://blog.csdn.net/wu_xianqiang/article/details/115425818<br>
NonNullable 从T中剔除null和undefined。 NonNullabl<T>
参考:https://zhuanlan.zhihu.com/p/85952443
*tsconfig.json
https://blog.csdn.net/weixin_43294560/article/details/107485120
常用知识点
TypeScript中有哪些高级类型?
类型保护
索引类型<br>
类型映射<br>
条件类型
https://www.jianshu.com/p/612b9e25e427
interface User {<br> name: string<br> age: number<br> contry: string<br> friend: {<br> name: string<br> sex: string<br> }<br>}<br><br>type CusPartial<T> = {<br> [P in keyof T]+?: T[P] extends object ? CusPartial<T[P]> : T[P]<br>}<br>
implements和extends区别?<br>
extends表示继承关系、implements表示实现关系
extends
子类继承(class)<br>
继承类只能是单继承,也就是如果父亲属于类(class),那么父亲只能有一个
类(class)/ 接口(interface)
继承接口可以是多继承,也就是如果父亲是接口(interface)那么可以有多个父亲
interface和type区别?
相同点
1、都可以描述一个对象或者函数
2、interface和type都可以拓展,并且两者并不是互相独立的,也就是说interface可以extends type, type也可以extends interface. 虽然效果差不多,但是语法不同。
不同点
1、type可以声明基本类型别名、联合类型、元祖等类型
2、type语句中还可以使用typeof获取实例的类型进行赋值
3、interface能够声明合并
总结
1、类型别名可以为任何类型引入名称。例如基本类型,联合类型等
2、类型别名不支持继承
3、类型别名不会创建一个真正的名字
4、类型别名无法被实现(implements),而接口可以被派生类实现
5、类型别名重名时编译器会抛出错误,接口重名时会产生合并
6、尽量使用interface避免使用类型别名
const和readonly的区别是什么?
1、const用于变量,readonly用于属性
2、const在运行时检查,readonly在编译时检查
3、使用const变量保存的数组,可以使用push,pop等方法。但是如果使用ReadonlyArray<number>声明的数组不能使用push,pop等方法
枚举和常量的区别?
1、枚举会被编译时会编译成一个对象,可以被当作对象使用
2、const 枚举会在 typescript 编译期间被删除,const 枚举成员在使用的地方会被内联进来,避免额外的性能开销
注:使用 常量枚举 会有更好的性能。
keyof、typeof、in 说明<br>
keyof:提取key键值后组合成联合类型
interface Person {<br> name: string;<br> age: number;<br> }<br> type keys = keyof Person;<br> // type keys = 'name' | 'age'<br>
typeof:<br>1、获取变量的声明类型<br>2、作为类型操作符后面只能跟变量<br>3、返回对象字面量的结构类型,同样适用于嵌套对象<br>4、变量没有声明类型,typeof返回变量的推断类型
typeof 1 // 'number'<br>typeof true // boolean<br>typeof 'hello world' // 'string'<br>typeof function(){} // 'function'<br>typeof {} // 'object'<br>typeof [] // 'object'<br>typeof null // 'object'<br>typeof undefined // 'undefined'<br>typeof new RegExp() // 'object'<br>typeof Symbol() // symbol
示例1:const n: number = 1<br>type t = typeof n // t => number<br>
示例2:<br>type T = typeof 's' // 错误<br>const s = 's'<br>type T = typeof s<br>
示例3:constt obj = {name:'zhangsan', age:28, isShow:true, run:()=>'run'}<br>type te= typeof obj<br>// te 等同于<br>type te {<br> name: string<br> age: numbre<br> isShow: boolean<br> run:()=> string<br>}<br>
示例4:<br><br>const s1 = 'hello'<br>type TS = typeof s1 // TS = string
in: 类似循环中的in,一般结合[]一起使用
type Property = 'name' | 'age' | 'phoneNum';<br><br>type PropertyMap = {<br> [key in Property]: string;<br>}<br><br>// type PropertyMap = {<br> name: string;<br> age: string;<br> phoneNum: string;<br>}
typeof和keyof结合使用
const colors = {<br> red: 'Red',<br> green:'Green',<br> blue:'Blue'<br>}<br><br>type TColors = keyof typeof colors // 'red' | 'green' | 'blue'
const colors = {<br> red: 'Red',<br> green:'Green',<br> blue:'Blue'<br>}<br><br>type Colors = typeof colors<br><br>type ColorMap = {<br> [p in keyof Colors]?: Colors[p]<br>}<br>or<br>type ColorMap1 = Partial<Colors><br>// 结果完全一致<br><br>// 类型高级类型的中的实现方式<br>type Partial<T> = {<br> [P in keyof T]?: T[P]<br>}<br><br>
keyof和[]一起使用
const person = {<br> name:'zhangsan',<br> age:28,<br> child:{<br> name:'zhangxiaosan',<br> age:5<br> }<br>}<br>type P = typeof person<br>type Child = P['child']<br>
小知识点
identifier!从identifier的类型里去除了null和undefined
function test(str: string | null) {<br> return str!.length<br>}<br>test('123')<br>
any和unknown区别
any任何类型,就相当于什么校验都不做
unknown在未知类型,直接使用会报错,需要指定类型后使用<br>例如:const a:unknown = 12; const b = a.toFiexd(2) 报错<br> const b = (a as number).toFiexd(2)
ts中的关键字type、interface、typeof、keyof、in、extends、infer;以及()、[]、{}、=、<>、:、;、?、&、|等界限符