2019-08-30
TypeScript
0

目录

tsc命令
基本类型
string
number
boolean
void
null 和 undefined
never
any
数组
元祖
对象
enum
类型断言
类型总结
interface
可选属性
只读属性
属性检查
函数类型
可索引类型
混合类型
类类型
参数检查
返回值检查
静态类型检测
接口继承
接口继承类
type
函数
类型推断
this
重载(ts提供)
类型保护

TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集,提供了静态类型检查、面向对象编程、泛型等高级特性,可以使 JavaScript 代码更加可读、可维护和可扩展。随着 TypeScript 在前端开发中的广泛应用,学习 TypeScript 已经成为了前端开发者必不可少的技能之一。

tsc命令

使用tsc命令,并且指定编译文件时,不会使用tsconfig.json文件进行编译

shell
tsc idnex.ts

使用tsc命令,并且不添加任何参数时,会使用tsconfig.json文件进行编译

tsc

基本类型

string

ts
let str:string='bob'

number

ts
// 普通数字类型(默认十进制) let decLiteral: number = 20 // 主动设置进制 let hexLiteral: number = 0x14 //(16进制) let binaryLiteral: number = 0b10100 //(2进制) let octalLiteral: number = 0o24 //(8进制)

boolean

ts
// 主动申明类型,申明isDone为boolean类型,后续isDone只能为boolean类型 let isDone: boolean = false // Ts默认指定初次类型,ts会默认为boolean类型,后续isDone只能为boolean类型 let isDone = false

void

通常我们用于函数。当一个函数没有返回值时,你通常会见到其返回值类型是 void

声明一个 void 类型的变量没有什么大用,因为你只能为它赋予 undefined 和 null(因为 undefined 和 null是所有类型的子类型)

ts
function warnUser():void{ console.log('This is my waring message') }

null 和 undefined

默认情况下 null 和 undefined 是其他任意类型的子类型(除了never), 就是说你可以把 null 和 undefined 赋值给其他类型的变量。

null和undefined使用

ts
let u: undefined = undefined let n: null = null

可以赋值给其他类型

ts
let str:string='boo' str=null

严格检查 如果开启严格检查,将无法任意赋值给其他类型,只能赋值给void类型(undefined)

ts
let str:void = null //无法生效 let str:void = undefined //可以生效

也许在某处你想传入一个 string 或 null 或 undefined,你可以使用联合类型 string | null | undefined

never

never 类型表示的是那些永不存在的值的类型。never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never 类型,当它们被永不为真的类型保护所约束时。 never 是其它类型(包括 null 和 undefined)的子类型

ts
function error(message:string):never{ throw new Error(message) } function loop():never { while(true){ } }

any

any跳过类型检查,可以为任何值,但是无法赋值给never

ts
let notSure: any = 4 notSure = 'maybe a string instead' notSure = false let list:any []=[1,'2',true] let list1:Array<any>=[1,'2',true]

数组

申明全为数字的数组

ts
//  第一种,可以在元素类型后面接上 let list:number []=[1,2,3,4,5] // 第二种方式是使用数组泛型,Array<元素类型> let list:Array<number>=[1,2,3,4,5]

数组类型错误示范

let list:[]=[1,2,3,4,5] // Error let list:Array=[1,2,3,4,5] // Error

多维数组使用

ts
function f(arr:number [][]){ // 定义类型的时候,二维数组时为[][] } f([[1,2,3],[4,5,6]])

元祖

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

ts
let x:[number,string]=[1,'hello'] let x:[number,string]=[1,'hello',1] // Error 超过已定义的元素数量,会报错

当访问一个已知索引的元素,会得到正确的类型

console.log(x[0].substr(1)) // Error console.log(x[1].substr(1))

对象

ts
// 第一种定义方式 declare function create(o:object|null):void create({prop:0}) // 第二种定义方式 let obj:object|null={} obj=null

enum

enum 类型是对 JavaScript 标准数据类型的一个补充

key值必须是字母开头,value必须是数字

默认情况下,从 0 开始为元素编号

ts
enum Color {Red, Green, Blue} let c= Color.Red console.log(c) //0

提供反查功能

ts
enum Color {Red, Green, Blue} let c= Color.Red let d=Color[0] console.log(c,d) //0,'Red'

类型断言

有时候你会遇到这样的情况,你会比 TypeScript 更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。

尖括号”语法方式

ts
let someValue: any = 'this is a string' let strLength: number = (<string>someValue).length

as 语法

ts
let someValue: any = 'this is a string' let strLength: number = (someValue as string).length

类型总结

string number boolean null any void => undefined => never array object void
  • any类型可以等于任意值(无法赋值给never)
  • never是所有类型的子类型,无法接受其他赋值,只能赋值给别人。
  • 赋值时只是赋这个变量,而不是类型,赋值时,ts是比较的类型,而不是值。
ts
let a:any='1' let n:number=1 n=a n='2' // err n=2 // ok

interface

可选属性

ts
interface SquareConfig { color?: string, width?: number, height:number }

color和width为可选属性,非必填项。 height为必填属性。

只读属性

ts
interface Point { readonly x:number, readonly y:number } let p1:Point={x:10, y:20} p1.x=30 // Error

属性检查

image.png

问题:使用到接口未定义的值时,会报错。

方案一:类型断言

ts
let mySquare=createSquare({colour:'123'} as SquareConfig)

方案二:字符串索引联合签名

ts
interface SquareConfig { color?: string, width?: number, [propName:string]:any }

方案三:将这个对象赋值给一个另一个变量(不推荐,逃避检查)

ts
let options={colour:'123'} let mySquare=createSquare(options )

函数类型

  • 对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配
  • 参数的个数以及返回值需要和接口定义的相同
ts
interface SearchFunc { (source:string,subString:string):boolean } let mySearch:SearchFunc=function(src,sub){ let result=src.search(sub) return result>-1 }

可索引类型

申明当用数字索引时,返回的值只能是string类型

ts
interface StringArray { [index: number]: string } let myArray: StringArray myArray = ['Bob', 'Fred'] let myStr: string = myArray[0]

混合类型

ts
interface Counter { (start: number): string interval: number reset(): void } function getCounter(): Counter { let counter = (function (start: number) { }) as Counter //将couter断言为Counter counter.interval = 123 counter.reset = function () { } return counter } let c = getCounter() c(10) c.reset() c.interval = 5.0

类类型

当一个类实现了一个接口时,只对其实例部分进行类型检查。

constructor 存在于类的静态部分,所以不在检查的范围内。

不会对函数参数部分进行检查,但是会对返回值进行检查(void行为怪异)

参数检查

接口设置的参数不会被默认继承到类的参数里面

例子1:类里的函数参数没有被类型检查

ts
interface Clock { a(x:string,y:string):void } class C implements Clock{ a(x,y){ return 10 } } let c=new C() c.a('1',33) // 成功 y值为string,但是设置为数字类型也通过了,说明类的参数里面没有类型要求

例子2:类里的函数参数需手动设置类型检查

ts
interface Clock { a(x:string,y:string):void } class C implements Clock{ a(x:string,y:string){ // 类型改成number,会报错,需要和接口里面申明的一致 return 10 } let c=new C() c.a('1','12') // 正确,参数改成数字会报错

返回值检查

返回值设置为string,number等这些类型,会被检查,设置为void不会被检查

例子1:string返回值检查

ts
interface Clock { a():string } class C implements Clock{ a(){ return 1 // 错误,改成'1'即可 } }

例子2:void返回值不检查

ts
interface Clock { a():void } class C implements Clock{ a(){ return 1 // 正确,改成‘1’也可以,改成任意值都可以。怀疑设置成void的时,不会进行返回值检查 } }

静态类型检测

ts
interface Interface { new(hour: number, minute: number) } class DigitalClock { constructor(hour,minute) { } } let A:Interface=DigitalClock let b=new A(1,2)

接口继承

ts
interface Shape { color:string } interface PenStroke { penWidth:number } interface Square extends Shape,PenStroke{ sideLength:number } let square={} as Square //接口断言时,如s as Square,s必须包含Square,但是{ } 不用 square.color='blue' square.penWidth=5.0 square.sideLength=10

接口继承类

当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的 private 和 protected 成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。 实际发现会继承类的成员包括实现

ts
class Control { private state: any } interface SelectableControl extends Control { select(): void } // 说明:SelectableControl 会继承私有属性private state: any class ImageC implements SelectableControl { // Error:“ImageC”类型缺少“state”属性。 select() { } } class Button extends Control implements SelectableControl { //先继承Control 私有属性 select() { } }

type

ts
type Easing = 'ease-in' | 'ease-out' | 'ease-in-out' let a:Easing='ease-in' // OK let b:Easing='ease' // ERR

函数

类型推断

ts会自己根据类型进行推断

ts
// 第一种 let myAdd:(x:number,y:number)=>number=function(x,y){ return x+y } // 第二种 let myAdd=(x:number,y:number):number=>{ return x+y }

this

ts
interface Deck { name:string, getName(this:Deck):()=>String } let deck:Deck={ name:'str', getName:function (this:Deck) { return ()=>{ return this.name } } } let f1=deck.getName() console.log(f1())

重载(ts提供)

ts
function pickCard(x:number,b:string):number function pickCard(x:string,b:number):string function pickCard(x,y):any{ return x } console.log(pickCard('1',2))

类型保护

typeof类型保护

ts
let a:string|number if(typeof a==='string'){ console.log(a.length) // OK console.log(a.toFixed()) // ERR } if(typeof a==='number'){ console.log(a.length) // OK console.log(a.toFixed()) // ERR }

instanceof 类型保护

ts
class Bird { fly () { console.log('bird fly') } } class Fish { swim () { console.log('fish swim') } } function getRandomPet () { return Math.random() > 0.5 ? new Bird() : new Fish() } let pet = getRandomPet() if (pet instanceof Bird) { pet.fly() } if (pet instanceof Fish) { pet.swim() }

本文作者:BARM

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!