typescript类型检查机制(day03)
typescript类型检查机制
TypeScript编译器在做类型检查时,所秉承的一些原则,以及表现出的一些行为。
- 作用:辅助开发,提高开发效率
- 类型推断
- 类型兼容性
- 类型保护
-
类型推断:
不需要指定变量的类型(函数的返回值类型),TpyeScript可以根据某些规则自动地为其推断出一个类型。-
基础类型推断
-
在src下新建 advanced.ts
// advanced.ts // 类型推断之基础类型推断 // 从右向左推断 let a = 1 //number let b = [] //[any] let b1 = [1] //[number] let b2 = [1, null] //[number|null] let c = (x = 1) => x + 1 //x number c number //从左向右推荐,上下文类型推断 // window.onkeydown = (event) => { // console.log(event.button) // } // 类型断言 增加灵活性 需要对上下文有充足的预判 interface Foo{ bar: number } //不建议这样使用 let foo0 = {} as Foo foo0.bar = 1 //这样使用 let foo1:Foo = { bar: 1 }
-
-
类型兼容性
当一个类型Y可以复制给另外一个类型X时,我们就说类型X兼容类型Y
成员少的兼容成员多的
X兼容Y:X(目标类型) = Y(原类型)- 在 advanced.ts中追加
// 类型推断之类型兼容性 /** * X 兼容 Y: X(目标类型) = Y(源类型) */ let s: string = 'a' // s = null //字符型兼容null,字符型是Null的子类型 // 接口兼容性 interface X{ a: any; b: any; } interface Y{ a: any; b: any; c: any; } let x1: X = {a:1, b:2} let y1: Y = {a:1, b:2, c:3} x1 = y1 //y具备x所有属性,x兼容Y // y1 = x1 //报错 // 函数的兼容性,通常发生在相互赋值的情况下 type Handler = (a: number, b:number) => void function hof(handler: Handler){ return handler } //参数个数 目标函数的参数个数对应源函数的参数个数 let handler1 = (a: number) => {} hof(handler1) let handler2 = (a: number, b: number, c: number) => {} // hof(handler2) //报错 // 可选参数和剩余参数 let a11 = (p1: number, p2: number) => {} //固定参数 let b11 = (p1?: number, p2?: number) => {} //可选参数 let c11 = (...args: number[]) => {} //剩余参数 //固定参数 可以兼容 剩余参数和可选参数 a11 = b11 a11 = c11 //可选参数 不兼容 剩余参数和固定参数 ===》 strictFunctionTypes": false 实现兼容 b11 = c11 b11 = a11 //剩余参数 可以兼容 可选参数和固定参数 c11 = a11 c11 = b11 //参数类型 需要匹配 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 //p3d 兼容 p2d p2d = p3d //p2d 不兼容 p3d 注释"strictFunctionTypes": false,兼容 //返回值类型 目标类型的返回值类型必须与源函数的返回值类型相同 成员少的兼容成员多的 let f11 = () => ({name: 'Alice'}); let g11 = () => ({name: 'Alice', location: 'BeiJing'}); f11 = g11 //f11 兼容 g11 // g11 = f11 //g11 不兼容 f11 // 函数的重载 目标函数的参数要多于源函数的参数 function overload(a: number, b:number): number; function overload(a: string, b:string): string; function overload(a: any, b: any): any{} // 枚举兼容性 enum Fruit {Apple, Banana} enum Color {Red, Yellow} //枚举类型和数值类型可以完全互相兼容 let fruit: Fruit.Apple = 3 let no: number = Fruit.Apple //枚举之间是完全不兼容的 // 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 //如果两个类中含有私有成员,只有父子类可以相互兼容 // private name: string = '' } let aa = new A(1, 2); let bb = new B(1) aa = bb bb = aa class C1 extends A{} let cc = new C1(1, 2) aa = cc cc = aa //泛型的兼容性 interface Empty<T>{ // value: T } let obj11: Empty<number> = {}; let obj22: Empty<string> = {}; obj11 = obj22 //泛型函数 let log11 = <T>(x: T) => { console.log('x') return x } let log22 = <U>(y: U): U => { console.log('u') return y } log11 = log22
- 口诀:
结构之间兼容:成员少的兼容成员多的
函数之间兼容:参数多的兼容参数少的
- 在 advanced.ts中追加
-
类型保护
TypeScript能够在特定的区块中保证变量属于某种确定的类型。
可以在子区块中放心地应用此类型的属性, 或者嗲用此类型的方法。- 在 advanced.ts中追加
// 类型检查机制之类型保护 enum Type { Strong, Week } class Java { helloJava() { console.log('hello java') } java: any } class JavaScript { helloJavaScript() { console.log('hello javascript') } javascript: 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() // 4 if (isJava(lang)) { lang.helloJava() } else { lang.helloJavaScript() } // if ((lang as Java).helloJava) { // (lang as Java).helloJava() // } else { // (lang as JavaScript).helloJavaScript() // } // 1 instanceof if (lang instanceof Java) { lang.helloJava() } else { lang.helloJavaScript() } // 2 in if ('java' in lang) { lang.helloJava() } else { lang.helloJavaScript() } // 3 typeof if (typeof x === 'string') { x.length } else { x.toFixed(2) } return lang } getLanguage(Type.Strong, '1')
- 在 advanced.ts中追加