QX-AI初始化中...
暂无预设简介,请点击下方AI实时简介按钮。
初识
TypeScript 是由巨硬开发的 JS 的超集,通过添加可选的静态类型和基于类的面向对象编程思想,使得代码更易于理解、维护和重构。此外,TS 还支持其他高级语言功能,如接口、泛型、命名空间和装饰器等
规范:TS 提供了更好的类型检查和代码提示工具,并且可以使用第三方库中的类型声明文件进行代码补全和类型检查
开发:TS 为现代Web应用程序和大型项目提供了一个强大的编程环境,可以帮助开发人员减少错误、提高开发效率和代码质量
运行:TS 可以转换成 JS 并在任何支持 JS 的环境中运行,包括浏览器、Node.js和移动应用程序等
安装:npm install typescript -g
会在全局暴露一个 tsc 命令
tsc -init
初始化,创建 tsconfig.json
tsc -w
监视所有 TS 文件变化,实时编译成 JS
npm install ts-node -g
安装 ts-node 更方便地运行 TS
配置文件
tsconfig.json 是 TS 的配置文件
可以定义哪些文件需要包含在编译过程中、使用哪个ECMAScript目标版本、生成哪种模块系统、是否开启严格模式等等
常用配置项:
- target 设置编译后的 JavaScript 代码使用的 ECMAScript 版本,默认为 ES3,可设置为 ES5、ES6/ES2015、ES7 等。
- strict 开启所有严格类型检查选项,包括noImplicitAny,noImplicitThis,alwaysStrict等等。如果希望 TypeScript 给出尽可能多的类型检查错误提示,可以将此选项设置为 true。
- module 指定生成的模块规范类型,可选值有 commonjs、amd、system 和 es2015。
- lib 指定编译过程中需要引入的库文件,默认情况下只包含 DOM 和 ES 标准库,可以通过指定其他库来获得更好的类型检查支持。
- moduleResolution 指定模块解析策略,可选值有 classic、node、和 yarn pnp。
- esModuleInterop 简化导入cjs模块功能
- outDir 输出目录,指定编译后的 JavaScript 代码所在的目录。
- rootDir 项目根目录
- allowJs 允许编译器编译 .js 文件(通常是为了容易迁移现有的 JavaScript 项目到 TypeScript 项目)
- sourceMap 生成 sourcemap 文件,方便调试 TypeScript 代码时能够正确地映射回原始的 TypeScript 代码。
- noImplicitAny 当 TypeScript 无法推导出变量的类型时,给出一个错误提醒
- noImplicitThis 禁止 this 关键字的隐式 any 类型
- strictNullChecks 严格模式下对 null 和 undefined 的检查。
TS检查相关注释
(1) // @ts-nocheck
加到文件首行,当前文件不需要 ts 校验
(2) // @ts-check
加到文件首行,对当前文件进行 ts 校验
(3) // @ts-ignore
忽略下一行代码的 ts 校验
(4) // eslint-disable-next-line
忽略下一行代码的 eslint 校验
(5) /* eslint-disable */
eslint忽略
类型标注
通过 <数据>:<类型>
对变量、函数返回值、函数参数等数据进行类型的标注、限制
思想:定义任何东西的时候要注明类型,调用任何东西的时候要检查类型。
可以标注的类型:
(1) 基础类型:Boolean、Number、String、null、undefined 以及 ES6 的 Symbol 和 ES10 的 BigInt。
(2) 空值:Void
(3) 顶级类型:任意类型 Any 和 不知道的类型 Unknown
(4) Object、object 和 {}
(5) 接口和对象类型:interface定义
(6) 数组类型
(7) 函数类型
基本类型
1、字符串类型:string
1 2 3
| let str: string = "chuckle"; str = `1+1=${1+1}`; str = "1+1=" + "2";
|
2、数字类型:number
1 2 3 4 5
| let num: number = 1 num = NaN num = Infinity num = 0xf00d num = 0b1010
|
3、布尔类型:boolean
注意:new Boolean() 返回的是一个 Boolean 对象,而不是布尔值
1 2
| let bool: boolean = true bool = Boolean(0)
|
4、Null 和 undefined 类型
undefined 和 null 是所有类型的子类型,在非严格模式下可以赋给其它任何类型的变量
严格模式下:
(1) undefined 和 null 不能赋给其它类型的变量,但 undefined 可以赋给 void 类型(一般也用不到)
(2) null 和 undefined 类型也不能相互赋值
1 2 3 4 5 6
| let a: null = null let b: undefined = undefined a = b let str: string = a let c: void = null c = undefined
|
空值void
JS 中没有空值的概念,TS 中可以使用 void 表示函数无返回值
注意:
(1) 不能将 void 赋给除 any 外其它类型的变量。
(2) 使用 any 类型的变量接收函数返回的空值,打印 undefined
(3) Boolean(void) 值是 false
1 2 3 4 5 6
| function fun(): void{} let a: any = fun(); console.log(a); a = Boolean(fun()); console.log(a); let b: string = fun()
|
any和unknown
any 和 unknown 是 TS 中的顶级类型,可以包含所有类型的数据
如果所有变量都是 any 类型,那就是 AnyScript,写起来和 JS 没什么区别,最好不要这么做
1 2 3 4
| let a: any = 1; a = "qx" a = true a = null
|
any 与 unknown 的区别:
any 可以赋给其它类型,而 unknown 不能赋值给除 any 和 unknown 以外的其它类型
1 2 3 4 5
| let a: any = 1 let b: unknown = 2 let num: number = a a = b num = b
|
unknown 类型不能读任何元素、属性,也不能调用任何方法,所以 unknown 比 any 安全
1 2 3 4 5
| let u: unknown = { a: 1 } console.log(u); console.log(u.a); u = ()=>{ console.log('@@') } u()
|
Object、object和{}
Object、object 和 {} 虽然能保存的数据类型不同,但都和 unknown 类型一样,不能读任何元素、属性,也不能调用任何方法
1、Object 类型是所有 Object 类的实例的类型,字面量 {} 代表的也是 Object
由于原型链顶层就是 Object,所有基本数据类型和引用类型最终都指向 Object,所以他也包含所有类型
1 2 3 4 5
| let obj: Object = 1; obj = "chuckle" console.log(obj); obj = { a: 1 } console.log(obj.a);
|
2、object 代表所有非值类型的类型(数组、对象、函数)等,常用于泛型约束
1 2 3 4 5 6
| let o: object = ()=>{ console.log('@@') } o() o = ['1','2'] console.log(o[1]) o = { a: 1 } console.log(o)
|
接口和对象类型
在 TypeScript 中,使用接口(Interfaces)来定义对象的类型。
即使用 interface 来定义一种对对象的约束
接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象外,也常用于对象的形状的描述。
1 2 3 4 5 6 7 8 9 10 11
| interface Person{ name: String, age: number, }
let person: Person = { name: "chuckle", age: 20 }
|
1、重名的接口会合并,共同起作用
1 2 3 4 5 6 7 8 9 10 11
| interface Person{ name: String, } interface Person{ age: number, } let person: Person = { name: "chuckle", age: 20 }
|
2、任意属性 [propName: string] (索引签名)
声明的对象中可以有任意个数所定义的类型(或其子类型)的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| interface Person{ name: String, age: number, [propName: string]: any } let person: Person = { name: "chuckle", age: 20, a: 1, b: "qx", c(){ console.log(this.a) } }
|
3、readonly 让属性只读
1 2 3 4
| interface Person{ readonly name: String, age: number, }
|
4、定义对象中的函数
1 2 3
| interface Person{ fun: (value:number)=>number }
|
6、接口继承 extends
1 2 3 4 5 6 7 8 9 10 11
| interface A{ name: String, } interface B extends A{ age: number, } let b: B = { name: "chuckle", age: 20, }
|
数组类型
使用 :<元素类型>[]
来定义一个数组
使用泛型的方式定义
定义二维数组
1 2
| let arr: number[][] let arr: Array<Array<number>>
|
定义包含多种类型的数组
1
| let arr: (number|string)[] = [1, 2, '3', 4]
|
元组:元素的类型、位置、个数必须一一对应
1
| let arr: [number,string] = [1,'qx']
|
函数类型与定义
定义一个函数类型变量
1 2
| let fun: Function fun = ()=>{}
|
定义函数的参数和返回值
1 2 3 4
| function fun(a:number, b:number):number{ return a+b; } console.log(fun(1,1))
|
使用 interface 定义函数类型(函数也是一种对象)
1 2 3 4 5 6 7 8 9 10
| interface Fn { (name: string): number } let fun: Fn = (name)=>{ console.log(name) return 1 } fun("chuckle")
|
TS 可以定义函数中的 this 类型,用于增强补全,必须写在函数的第一个参数上,不作为真正的参数定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| interface Obj{ name: string add: (this:Obj, num:number)=>void } let obj:Obj = { name: "chuckle", add(num:number){ console.log(num); console.log(this.name); } } obj.add(1);
|
?可选符
使用 ?:
定义函数参数或对象属性作为可选项
1 2 3 4 5 6 7 8 9
| interface Person{ name: String, age?: number, }
function fun(a:number, b?:number):number{ return b ? a+b : a; }
|
联合类型
使用 <类型1>|<类型2>
标注多个类型
1 2 3 4
| function fun(a: number | string) { }
let a: number | string
|
交叉类型
<类型1>&<类型2>
需同时满足两种类型,通常配合接口使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| interface Student { name: string id: number } interface Person { name: string age: number } let p: Student & Person = { name: "chuckle", id: 1, age: 20 }
|
类型断言
值 as 类型
或<类型>值
欺骗 TypeScript 编译器,但无法避免运行时的错误
1 2 3 4 5 6
| function fun(a: number | string){ console.log((<string>a).length); } fun(123) fun('123')
|
TS 直接在 window 上添加属性是不允许的,但可以将 window 断言为 any 类型,就可以添加属性了
1 2 3
| window.a = 1; (<any>window).a = 1; console.log((<any>window).a);
|
内置对象
JS 中有很多内置对象,它们可以直接在 TS 中当做定义好了的类型来使用
1、ECMAScript 的内置对象:内置对象名就是类型名
1 2 3 4 5 6 7 8 9 10 11 12 13
| let b: Boolean = new Boolean(1) console.log(b) let n: Number = new Number(true) console.log(n) let s: String = new String('chuckle') console.log(s) let d: Date = new Date() console.log(d) let r: RegExp = /^123/ console.log(r) let e: Error = new Error("error") console.log(e)
|
2、DOM 和 BOM 的内置对象:
HTML<标签名>Element
某个内置标签的类型,input、span 等
HTMLElement
语义化的标签名,footer、header,以及自定义标签名
Element
任何标签元素的类型
NodeList
任何元素集合的类型
NodeListOf<其它类型>
指定元素集合的类型
由于元素可能获取不到,要加上 null 组成联合类型
1 2 3 4 5 6
| let div1: HTMLInputElement | null = document.querySelector('input'); let div2: HTMLDivElement | null = document.querySelector('div'); let div3: NodeListOf<HTMLElement> | null = document.querySelectorAll('.content'); let local: string | null = localStorage.getItem('token') let lct: Location = location let pms: Promise<number> = new Promise((r)=>r(1))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| interface HTMLElementTagNameMap { "a": HTMLAnchorElement; "abbr": HTMLElement; "address": HTMLElement; "applet": HTMLAppletElement; "area": HTMLAreaElement; "article": HTMLElement; "aside": HTMLElement; "audio": HTMLAudioElement; "b": HTMLElement; "base": HTMLBaseElement; "bdi": HTMLElement; "bdo": HTMLElement; "blockquote": HTMLQuoteElement; "body": HTMLBodyElement; "br": HTMLBRElement; "button": HTMLButtonElement; "canvas": HTMLCanvasElement; "caption": HTMLTableCaptionElement; "cite": HTMLElement; "code": HTMLElement; "col": HTMLTableColElement; "colgroup": HTMLTableColElement; "data": HTMLDataElement; "datalist": HTMLDataListElement; "dd": HTMLElement; "del": HTMLModElement; "details": HTMLDetailsElement; "dfn": HTMLElement; "dialog": HTMLDialogElement; "dir": HTMLDirectoryElement; "div": HTMLDivElement; "dl": HTMLDListElement; "dt": HTMLElement; "em": HTMLElement; "embed": HTMLEmbedElement; "fieldset": HTMLFieldSetElement; "figcaption": HTMLElement; "figure": HTMLElement; "font": HTMLFontElement; "footer": HTMLElement; "form": HTMLFormElement; "frame": HTMLFrameElement; "frameset": HTMLFrameSetElement; "h1": HTMLHeadingElement; "h2": HTMLHeadingElement; "h3": HTMLHeadingElement; "h4": HTMLHeadingElement; "h5": HTMLHeadingElement; "h6": HTMLHeadingElement; "head": HTMLHeadElement; "header": HTMLElement; "hgroup": HTMLElement; "hr": HTMLHRElement; "html": HTMLHtmlElement; "i": HTMLElement; "iframe": HTMLIFrameElement; "img": HTMLImageElement; "input": HTMLInputElement; "ins": HTMLModElement; "kbd": HTMLElement; "label": HTMLLabelElement; "legend": HTMLLegendElement; "li": HTMLLIElement; "link": HTMLLinkElement; "main": HTMLElement; "map": HTMLMapElement; "mark": HTMLElement; "marquee": HTMLMarqueeElement; "menu": HTMLMenuElement; "meta": HTMLMetaElement; "meter": HTMLMeterElement; "nav": HTMLElement; "noscript": HTMLElement; "object": HTMLObjectElement; "ol": HTMLOListElement; "optgroup": HTMLOptGroupElement; "option": HTMLOptionElement; "output": HTMLOutputElement; "p": HTMLParagraphElement; "param": HTMLParamElement; "picture": HTMLPictureElement; "pre": HTMLPreElement; "progress": HTMLProgressElement; "q": HTMLQuoteElement; "rp": HTMLElement; "rt": HTMLElement; "ruby": HTMLElement; "s": HTMLElement; "samp": HTMLElement; "script": HTMLScriptElement; "section": HTMLElement; "select": HTMLSelectElement; "slot": HTMLSlotElement; "small": HTMLElement; "source": HTMLSourceElement; "span": HTMLSpanElement; "strong": HTMLElement; "style": HTMLStyleElement; "sub": HTMLElement; "summary": HTMLElement; "sup": HTMLElement; "table": HTMLTableElement; "tbody": HTMLTableSectionElement; "td": HTMLTableDataCellElement; "template": HTMLTemplateElement; "textarea": HTMLTextAreaElement; "tfoot": HTMLTableSectionElement; "th": HTMLTableHeaderCellElement; "thead": HTMLTableSectionElement; "time": HTMLTimeElement; "title": HTMLTitleElement; "tr": HTMLTableRowElement; "track": HTMLTrackElement; "u": HTMLElement; "ul": HTMLUListElement; "var": HTMLElement; "video": HTMLVideoElement; "wbr": HTMLElement; }
|
Class