TypeScript——类型检查机制
类型检查机制:TypeScript编译器在做类型检查时,所秉承的一些原则,以及表现出的一些行为。
作用:辅助开发,提高开发效率。
类型推断
:指不需要指定变量的类型(函数的返回值类型),TypeScript可以根据某些规则自行的推断出一个类型
1.基础类型推断
2.最佳通用类型推断
3.上下文类型推断
- 前两者都是从右往左的推断,根据值去推断, 例如 let a = 1 // a 被推断的类型是 number
let a = 1
- 最佳通用类型推断 例如 let b = [1, ‘a‘] // b 的最佳通用类型 (string | number)[]
let b = [1, ‘a‘] let c = (x = 1) => x + ‘2‘ // function(x: number): string
- 根据上下类型推断 例如 window.onkeydown = (event) => {} // 推断 event 为 KeyboardEvent
window.onkeydown = (event) => { console.log(event) }
关于类型断言
interface Foo { bar: number } let foo = {} as Foo foo.bar = 1 /** * 以上使用`as`的方式,不会提示是否缺失定义`bar`属性, * 最好的方式是使用下面代码,在定义时就指明类型 * * Property ‘bar‘ is missing in type ‘{}‘ but required in type ‘Foo‘. */ let foo02 : Foo = { bar: 1 }
类型兼容性:(当一个类型Y可以被赋值给另一个类型X时,可以说类型X兼容类型Y) =》X(目标类型)=Y(源类型)
- 口诀:
结构之间兼容:成员少的兼容成员多的
函数之间兼容:参数多的兼容参数少的
- 接口兼容性:成员少 兼容 成员多的(前提:源类型具备目标类型的必要属性 则可以向其兼容)
interface X { a: number; b: number; } interface Y { a: number; b: number; c: number; } let xx: X = { a: 1, b: 2} let yy: Y = { a: 1, b: 2, c: 3 } // yy = xx // Property ‘c‘ is missing in type ‘X‘ but required in type ‘Y‘ xx = yy // Ok 函数兼容性 type Handler = (a: number, b: number) => void function hof(handler: Handler) { return handler } // 1.参数个数 let handler1 = (a: number) => {} hof(handler1) let handler2 = (a: number, b: number, c: number) => {} // hof(handler2) // 源函数参数3个 而目标函数参数2个 所以不能达到兼容 // 可选参数和剩余参数 let a1 = (p1: number, p2: number) => {} let b1 = (p1?: number, p2?: number) => {} let c1 = (...arg: number[]) => {} // 固定参数可兼容可选/剩余 // a1 = b1 // a1 = c1 // 可选参数不可兼容固定/剩余 改变"strictFunctionTypes"为 false可进行兼容 // b1 = a1 // b1 = c1 // 剩余参数可兼容可选/固定 c1 = a1 c1 = b1 // 2.参数类型 // 简单类型 let handler3 = (a: string) => {} // hof(handler3) // 类型不兼容 // 复杂类型(对象) interface Point3D { x: number; y: number; z: number; } interface Point2D { x: number; y: number; } let p3d = (point: Point3D) => {}; let p2d = (point: Point2D) => {}; p3d = p2d // p2d = p3d // 成员多 兼容 成员多少的 改变"strictFunctionTypes"为 false可进行兼容 /* 3.返回值类型 Ts要求函数定理类型与返回值类型相同或为其子类型 * 少的可以兼容多的 */ let f1 = () => ({ name: ‘jessiex‘ }) let f2 = () => ({ name: ‘jessiex‘, age: ‘2‘ }) f1 = f2 // f2 = f1 // 无法兼容 枚举类型 enum Fruit { Apple, Banana } enum Color { Red, Yellow } let fruit: Fruit.Apple = 3 let no: number = Fruit.Apple // 枚举与number之间是相互兼容的 // let color: Color.Red = Fruit.Apple // 枚举之间相互不兼容 类类型 // 比较两个类是否兼容时,静态成员和构造函数是不参与比较的 class A { constructor(p: number,q:number) {} id: number = 1 private name: string = ‘‘ } class B { static s =1 constructor(p: number) {} id: number = 2 } let aa = new A(1,2) // let bb = new B(1) // aa = bb OK // bb = aa OK // 在拥有私有成员时,只有父类和子类之间相互兼容 class C extends A {} let cc = new C(1,2) cc = aa // (aa=bb)Fail aa = cc // (bb=bb)Fail
类型保护
指TS能够在特定的区块中保证变量属于某种确定的类型。可以再次区块中放心的引用此类型的属性,或者调用此类型的方法
enum Type { Strong, Weak } class Java { helloJava() { console.log(‘hello,Java‘) } java: any; } class JavaScript { helloJavaScript() { console.log(‘hello,JavaScript‘) } js: any; } function isJava(lang: Java|JavaScript): lang is Java { return (lang as Java).helloJava !== undefined } function getLanguage(type: Type, x: string | number) { let lang = type === Type.Strong ? new Java() : new JavaScript(); // 1.instanceof 通过判断一个实例是否属于某个类 if (lang instanceof Java) { lang.helloJava() } else { lang.helloJavaScript() } // 2.in 通过判断一个属性是否属于某个对象 if (‘java‘ in lang) { lang.helloJava() } else { lang.helloJavaScript() } // 3.typeof 通过判断一个变量的类型(借助变量x示范) if (typeof x === ‘string‘) { console.log(x.length) } else { x.toFixed(2) } // 4.类型保护函数:某些判断可能不是一条语句能够搞定的,需要更多复杂的逻辑,适合封装到一个函数内 if (isJava(lang)) { lang.helloJava() } else { lang.helloJavaScript() } return lang; }
相关推荐
changcongying 2020-11-02
changcongying 2020-10-30
苗疆三刀的随手记 2020-10-29
zouph000 2020-10-25
Jruing 2020-10-23
ctg 2020-10-14
PMJ0 2020-10-13
ChaITSimpleLove 2020-10-06
小飞侠V 2020-09-25
QiaoranC 2020-09-25
changcongying 2020-09-17
taizuduojie 2020-09-15
淼寒儿 2020-09-13
lyjava 2020-09-11
彤庆的技术 2020-09-02
锅哥 2020-08-27
ruanhongbiao 2020-08-16
zouph000 2020-08-03
Java编程语言学习 2020-07-29